From nobody Sat Apr 11 21:30:24 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=1773069066; cv=none; d=zohomail.com; s=zohoarc; b=GIBGWv3ebuXYLe7AnL490Ab1olhAFge2ZDqmarXXi9Cgw8zESlKwk0nLowFqfqzj/WMZY/3DLi+Dsvf33F7abBceiTNbN61Rtdq+XfMKA/sz+RsJDg2zojYHP2CMuWWTnSFdNyFto+23hbfmGIDpu0N/smVaQaBF4vxTsYNnRhk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069066; 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=QKrhJqwNlp9DMalsBKEho9jBGi+UNKYuJ5/HEX5Bsco+hSm66mRkM6ftnRmWOKC4tyNo856UrY9JpMUPcGTgzy6LgnWvIQhPYxvcQ+fxDaK9hNU5dP2OIQKZ7OMqL/cuziQiQr6Du6xpCJE2oabipTNeTFLmvDZ+LYT38AMbEuQ= 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 177306906675798.43781781281609; Mon, 9 Mar 2026 08:11:06 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcEP-0000bg-JC; Mon, 09 Mar 2026 11:09:17 -0400 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 1vzcEO-0000as-7L for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:16 -0400 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 1vzcEL-0008Hq-AA for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:15 -0400 Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-202-nPU_imrOOH6DdHWrn6IHfQ-1; Mon, 09 Mar 2026 11:09:11 -0400 Received: by mail-ej1-f72.google.com with SMTP id a640c23a62f3a-b8f848ebcbbso815831266b.0 for ; Mon, 09 Mar 2026 08:09:11 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-439dae2ba5bsm24847050f8f.22.2026.03.09.08.09.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068952; 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=fQuAqKsBF/vIIZy86DtNIN5I6NHNtmCE+oFFfcJKOePkeppGdBwchfY0ueoA3i48xAfdfZ cgUhRk1gAEcOnHTkndQIdqOikyA50mpb0V57oviw58UKABsXfWjuftFDFpCvdb730L9i98 x0E0LKs6eGsloYLKb+Atna6uIDcIMqk= X-MC-Unique: nPU_imrOOH6DdHWrn6IHfQ-1 X-Mimecast-MFC-AGG-ID: nPU_imrOOH6DdHWrn6IHfQ_1773068950 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068950; x=1773673750; 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=nPhAm6FIKMcNP0uDsbBUV2NLSYkAyZ2P0IYWEOrIzeGWj5INHF9ffu0ImIhKcyupMN VvNoVLUXeneqwszyP2eCvMB2nOmCylIgGxYFSz6zE/SfWWIBweNc2nEu6xZch0oOxWuO WusvtBjyUZE9U1BPv7fPeJddqxk5FMtq/onlYux5aVpU+30V4BFCwrhJwUS4LF4lLiNJ na3WJL++ryeQa5XZSfV+FgcSuJS1PYBjjUjWXAqLeNV01yDnxQwDGIlFHaypJBgfHWgU 4UNgx+3YyJHWJfa4lXxrf4hrxaXth9nDS7lyNhZnDfpp6Fob6Il5C2VoiIk/sgW86XLs vG1Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068950; x=1773673750; 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=b0BQX7o83xwH2guOmUtgtF99wX4hv3v2f+D0meF5M1jqI7I88kYnLBJ2xo/BUgSPuF 6n0mgOiRCyDxwrhNrIHPDrUhUiRuem56MfZnE+5gGqWArlnl0qX9NsBrP9LtllrlyUgm A0ITEG2Uo2NlODCi+FYU7gP3UfI4A/Mf63aBWk77DvOF+tjZuK3O+etbMLs+PN4g4vgi ohe9yZCremSDXSaGAAM+xB7f6KWLS/b1Qx3Z7AEskrhtVBrTc1WcpSVBgeitcOPANzxA JEeYlDFzL6GQ7JfUApetnl0xhwhyCR9/pK9u3rT9LUsRBOJiytj7nrHhVZxINYe117lG C/Qw== X-Gm-Message-State: AOJu0Yzx65BuW6qyFZ/eNfYRw768EgN3XApu1gcz6Q4BrzYq3r3VcbWh 0vfoWioNgwU3eGkr4abXQ74IdvHA3vPBctybPKDx8p29ELRIr+lkacoEM35wJoYZRlpMNxTENOp Xpva1huzRmx7laQhPB4gnpDxyUqk6xIxHM8FIe6kXTsXDR5bXX64Q6D1B6/ZtxY/p X-Gm-Gg: ATEYQzwQ2aI2+86Z9LVbYj1SP1cei1t9sZeciirm15PxIz2zsIub/peIJvtuOOEk6SI 1gyf2HOy4Gw628ONpwgXRTZ+dRpqKBt9619NDDTSybxNUSeB/NzSCiQ8vPTZesIDxJ5eiYQRt+4 muw37raqZ5tKNrX2tjPMetyP1mjTS00JoP4CDeKHXi0gczvlp2kB//KYP1tz/TVs7frFBHWQ8Tj ducReEzp3svsiaogce6oWE5m7GVcioKwIY7JNZhuuvF/FYBuBxnBCcOjZk0Q3k2aBHFfTgiovQx J3poD+nT6jqyZezJG/1fAzWnzSTrgMnUouj5M/QKNnI/zYJfpf34zPjga9PEBzfb9/kQcQNNG8b DQP9+yItv2sYY/fhCrAuRzHBylX8Z8c40gQbksxKEr3ACsrGWNC5HPz6AOJLFqgEJyZuZ2sI9UD WD1IFz X-Received: by 2002:a17:906:fe4c:b0:b87:1fe6:f223 with SMTP id a640c23a62f3a-b942dbafa2emr620155266b.6.1773068949892; Mon, 09 Mar 2026 08:09:09 -0700 (PDT) X-Received: by 2002:a17:906:fe4c:b0:b87:1fe6:f223 with SMTP id a640c23a62f3a-b942dbafa2emr620153166b.6.1773068949296; Mon, 09 Mar 2026 08:09:09 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 01/25] fuse: Copy write buffer content before polling Date: Mon, 9 Mar 2026 16:08:32 +0100 Message-ID: <20260309150856.26800-2-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069069781154100 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 Sat Apr 11 21:30:24 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=1773068996; cv=none; d=zohomail.com; s=zohoarc; b=eS0rwFJJrIwvWoMbJ2uvdr8yH54gwQFZmN1+DUUL3GPdGUQ7OCZGf4j3Cf2A2FJSbShCIipBag90R7OFA+L33L0AC02u9ylN+7byaZSsM+7g3RmcvTjoa9W/qlj9jkXD7rceS5o5LVqNCc5hb3Zs+vOAU2F0I7+443KCng6aFhk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773068996; 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=LIXvp4QlsrWdtP/QPOKDswgYoOx58GSRNTtWd36RuJnicbMJm4AvcNh4oZM0EYC2LFKZsOe0VV8KK71GR7PVmVGWBXu+LezaC6fqV/T4PXo07RueyOTvkZzbx7FThX5pAY5O2cgf/9GmSViIm8QH5ETWnckR4n9yXoEohF7Zbss= 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 1773068996762729.0799043436799; Mon, 9 Mar 2026 08:09:56 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcEP-0000cD-TI; Mon, 09 Mar 2026 11:09:17 -0400 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 1vzcEO-0000bN-O5 for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:16 -0400 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 1vzcEN-0008IN-B3 for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:16 -0400 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-445-m-o9joejMzSNlNxPwQj6fQ-1; Mon, 09 Mar 2026 11:09:13 -0400 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-4837bfcfe0dso138886095e9.1 for ; Mon, 09 Mar 2026 08:09:13 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-485345acc69sm46428185e9.25.2026.03.09.08.09.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068954; 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=Pq8uXTLK9hKBxu7F9zUpfcxk9ymEZ+NqEoKofjiopBDLccFlPzXXLSwF3TGhlRc4mxdJDN k+AoxuKmwuiUUAxKuoWth9OeE8cQuxm1UYXD0Xhbk01qQvjwa6BH6jGpoyqZXwvLAzyrB7 BvpzB9qv/D5wquTwAfzVCabA5V9jynw= X-MC-Unique: m-o9joejMzSNlNxPwQj6fQ-1 X-Mimecast-MFC-AGG-ID: m-o9joejMzSNlNxPwQj6fQ_1773068952 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068952; x=1773673752; 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=P5IRwU7+4wM/AP1tnpMigp8OkY/Me/VBvHpkp1Jn4MAsVKYz4Yk/gwFmUZ1EFv6wg3 tvR/jiY/xAHKUsMmrwQ1qx20T5uDRn7fUZpIfKx4JKlMgcZciXwWt0YMCavU/QMHbXcd iMyPKamnpFeXERcBHgMU0VdtT91PYl2QZknQIHn8q+cyHQ773wPpYvLi1WCc312WAB9n tWob8hI5nEk8vS6j8g4Ddtd9VDNNaGs17fmmGiK/w/UHF9jDKafW8wY8IWv3oRatRD09 3CWgyfcl7eoYKER2BrulwDXkthcpraBAy4CM9pa523IZxBQAJ/6vwHYDtutc4RbFrsll 0f3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068952; x=1773673752; 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=GS0grPAQrH8SX0kjQWW2AEH1+1Qxsg8jJi07vq/oEHwKjmMMAdqrfIc1N/nZedjG2u UwXOvpArMNnvZIoKArJeK1Eno8W9KOTvdHBedpSpYFbNXDe1WvDeTJUkKLyyJzqrlhsu sZVwSUXq+tYF11NKI+E9fdOqotjIUkmAJFgS4f/QsAXycBjz82NEEPcQMUFtcXkpunOJ RiT8WCS1b6NpINLRlHKuG18v+p353mkJ8PoV9k5hH+Xc8X6Ut/Lzy5OND1HbzHxN9sDf 7WoaoapcD+3FNO3S4X/ygjndQB6cEIXjuTxS/rFBMdrC1/bGj5bXwATSJLeUBNKDtWPp Hozw== X-Gm-Message-State: AOJu0YxKmpJ9PFdxXGXyMRSrB4I2rp6wM6g7oF/iVEU8g5IKfsRS7GTQ NZPgMNlQuX68K9ILrXdqjhiT2S4Fzvhe0vtx2gzRlBcjO0wn+0F4GfnbzFET6VR4JT/LLTVQr3F 6xzhlC8g593TahlxYkmsrnAZpotkV10+YUO2iBBh6ajloJv39NxIngzzP X-Gm-Gg: ATEYQzwz0XsKp1ReLKwagfzKeyMfXWc/4hd8JVzmTB4M1sIqvNtarszV2YJFJLGlNFi MlpAtN2uEWSaZobbX5oxTuRu52TtUy8wNwopvv1cVKhPuldOEUB67cXAqR2P/T1/EE80GKBgQ6h LNiaVUC2sKbRW5QYGZ+OKMQzX51BQ60KyliU4VXBp1NhszDrs2C5vHF/6C0lKOw4JDO3c0lVjjy /KF3lPtL6zTt0vTyWx0/AvvVxOIzYJt8Ll3M6VSVFfXdfnw/1eh4J0lkiE7rwNC+B0xN7HbrD9+ ypHkI0lHWGhF0br/GSqflGLvKF5oulFaRoEZ95IRObAqo3eE5WlIaLuTcSJxjAQ+l90liQaxXrw WMyvbVWyUF83lstPIN7vuxC9U50RBU9HSXLz3zBYLuE4lCRJGnxTqaU8XtSTfGSWKx/mK0w8olb +dgQkx X-Received: by 2002:a05:600c:8719:b0:485:40c6:f507 with SMTP id 5b1f17b1804b1-48540c6f66amr16944005e9.30.1773068952164; Mon, 09 Mar 2026 08:09:12 -0700 (PDT) X-Received: by 2002:a05:600c:8719:b0:485:40c6:f507 with SMTP id 5b1f17b1804b1-48540c6f66amr16943385e9.30.1773068951608; Mon, 09 Mar 2026 08:09:11 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 02/25] fuse: Ensure init clean-up even with error_fatal Date: Mon, 9 Mar 2026 16:08:33 +0100 Message-ID: <20260309150856.26800-3-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773068998609154100 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 --- 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 Sat Apr 11 21:30:24 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=1773068996; cv=none; d=zohomail.com; s=zohoarc; b=YtqyA5C7B4dVNtKgL4P8ym7uJXNx+DjbPf/Px1/YQGtoCDL7ihYJ3qMktuYgxURcHhFFiYdtRXt+c8ga1HbRiXDN/1idztLZa1lz/na/55rQQ8CsvU7EVtEim8BmLT/g3RoN01p2GnoP0N3cOj8xTZY0WgRQTcoxMItVWb/N3lU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773068996; 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=ParseivDjOqgosqg+RIeJiK/gNoLztg/hm8bBFsTOlHb26zUUM3oNLXN383Bd50eq6D2ClPTDrj04ZgAeiFfl2NBW+1jyXQ56zeu3+r4guivf9pvN2sEYrCNyG/4bIreV2d7i+XaQHKkQvgcpeDykrW7eDxQb7LQuh4LprGBsDg= 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 1773068996753287.0317375873078; Mon, 9 Mar 2026 08:09:56 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcES-0000fB-U7; Mon, 09 Mar 2026 11:09:20 -0400 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 1vzcEQ-0000dN-TZ for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:18 -0400 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 1vzcEP-0008JJ-GB for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:18 -0400 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-455-FYRWbj9CNYal02fwuGpI8g-1; Mon, 09 Mar 2026 11:09:15 -0400 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-485355493aeso3412905e9.1 for ; Mon, 09 Mar 2026 08:09:15 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-439dadb85b8sm27478391f8f.17.2026.03.09.08.09.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068956; 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=CfxJRv0S07MpXlxPIMOQrXXslksi7bTo4+q+OeI/uOx9KoxwO9gmyzwZKKrLHYP8xWGeVU ZVOrjWK0ljpzzMPyytgEB8CCq4x8pVc4jAV4TsZ/sUES74Oe7OHT8msn9Zled2WzGMj+uU gH6But1pc5hZNkB+/rTLAeWaBWVpwfU= X-MC-Unique: FYRWbj9CNYal02fwuGpI8g-1 X-Mimecast-MFC-AGG-ID: FYRWbj9CNYal02fwuGpI8g_1773068954 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068954; x=1773673754; 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=ZdidUdhVoQAJaym85CC/G2ebAyGLogjAmxTTnTmyKvkGvc84gFbtJO0NomZ/9N+RTT ZzGQVC3LVux+lcfbjhq6oIn69CsRm0Y8olOqlsaXVcV7hgdGiGVxoxd2TTl0Ra+sNap2 lKY47qYTaqCUwHX5uNVm7CFQql5n7RhUrIg2D+Yd0Uq2kUlxDvSHufjYELBy1mX4eMyn 7P9oAt/x6W7GuZ4oIyAkBJCHe4f8JyRWxc+4bO8Vx5d46NlvNzZlV/w6F9v0uIi9omWi 7kqt2k9egbmBTt0aFQ7J861l9COGbWHdAR8Za1NjGp8BePBjPrjoIM/xsJBv2dOoAbMd +5ng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068954; x=1773673754; 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=AdzvwTRZCSbgcnE1uXGE0v1LIMRr4xMVw+bVFFW3htZjp136RhhveDHO6iGvBmyCHn XgTVeJCWITUObGv0ue7ixebf/gfMmTpWRIAk87+pu8+c30Z8F3sDol2YNZxZwG1J4wam 8ip04VGZgd7W6XxtWHvS3yFAR4Ab3APdtE6U1Es0y5dTYnjf2xjgTHqJFYLYDCxffbtO vo/TCLY/sSRVO167slGJvsMcLfNuFAlBLf9NvFWN4f25eOBIN4dAALBrhmpex05k79hP dmXuA8dA0IpMhvlYxuP+BRFWDwSaAegIFdI1b+Zi9gX9ZhFpd6r9NLjrqzbawVueB7bJ Z/bg== X-Gm-Message-State: AOJu0Yxq6O2ST/hRX6ajwRzdGkomjVrazUGXS7DBdoco6862HH/Pzhek QyvdVSxiNyfwq/XYud6ajZ/UDjXF34dQuZMkTX6TcYZKy6/F4nQdfZCiP+QqCEY7QCWvBJLJhMA 5SQcqaEReze2BNshQab/5oe0HN7y2vuGHuYPSS5mwDhNmkQ1XR7vfqain X-Gm-Gg: ATEYQzyFj8C2AjiNMuPQklNEYXG5rGliyw3pXqctx+vg2KPHeh7bM0xY3BAr3x/Lr0n 5qWpgKY4AjnlfNKuURJIZdXlj58xOStuegLCqCSLsqo6KYdv0RAALEcoinUI6boAbpl1778KICu pP1VhpYcHYgfysUZ2ApmU4NF5Er7ZuxTrBWVfkfNbe0swNPrmTv0iCnUesrVaNGDTPvU6tItaCF HFMuzaEyF8dpxkWHXoQ1s//99LlPAsw0ENRWoBsXW+1zv2Y+C6pCKhlW2C4GKFm5CLlIT3ez5gd JwoMKxsm+A/LcfIISv7qzGFmN4aumcMdZ52NAhKAmlSRR6AAN+nqdGKO+8Qb1hUsGvUrQOr6TFo P0yrklrdN5HR9GHA/TzLg61AFr90Mc/YeG+2H0oZ+NjxewCy4sok3QbOMgjicw1WepFd9q3WhzU kqFD/J X-Received: by 2002:a05:6000:4205:b0:439:c9d0:5fd4 with SMTP id ffacd0b85a97d-439da656affmr20069351f8f.16.1773068954095; Mon, 09 Mar 2026 08:09:14 -0700 (PDT) X-Received: by 2002:a05:6000:4205:b0:439:c9d0:5fd4 with SMTP id ffacd0b85a97d-439da656affmr20069278f8f.16.1773068953595; Mon, 09 Mar 2026 08:09:13 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 03/25] fuse: Remove superfluous empty line Date: Mon, 9 Mar 2026 16:08:34 +0100 Message-ID: <20260309150856.26800-4-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773068998608154100 Content-Type: text/plain; charset="utf-8" Reviewed-by: Stefan Hajnoczi Signed-off-by: Hanna Czenczek --- 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 Sat Apr 11 21:30:24 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=1773069087; cv=none; d=zohomail.com; s=zohoarc; b=LydJELS7kpI3nTqGviOsg06eOrqjJ8L9HGHWp9yhqaGGOb2t7jAd02ZZ3EVHOy1enqE3S8QBHiChGwpY9JqGzrNDHh8WcE6zUqLzWMKQG86WcSmI0F0fNLtuavifmbND0JbKXYl5J1oGoJuvM/Fff4pVojJx8AmyZgtQtltCRNQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069087; 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=Xc1zuLJOgJ5ZgNP/yKlM1+Y4sK8JrEDjlaVH+3cnomtp8mHq/Y8ufZgaAErnlM8ttVdXEbeufwHxnsV06L0/dEDdfJ/Hi1OFJp75QtIA2VN961rXghgFueqzhU04yPSV3JoRl3YHijvx5roZtQl/MuPsmv2n3fW93ZKuDyXtfxg= 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 1773069087271454.1948929927612; Mon, 9 Mar 2026 08:11:27 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcEU-0000hD-8O; Mon, 09 Mar 2026 11:09:22 -0400 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 1vzcES-0000fA-Qf for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:20 -0400 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 1vzcER-0008Jv-ES for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:20 -0400 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-679-bJ_ivm-zOX---Gz9079qsQ-1; Mon, 09 Mar 2026 11:09:17 -0400 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-439cbc5fd75so4083655f8f.0 for ; Mon, 09 Mar 2026 08:09:17 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4853c784813sm63842925e9.5.2026.03.09.08.09.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068958; 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=QUU/21ZPUsexLWxlViJfjPnlrFpp8vKh+qd0gsKEf/c1Na1j7RqJl7ofUDeIExrsv411wQ 03hf6+TZtQcC4ohJpK4bvwsgxc+oHD1CdWQiLh1oHT5aCjh3FGjQYnYFhx6bna1s3+sOBx u/ooYLAf59g9UexIo0lAuRdYgtEKTIY= X-MC-Unique: bJ_ivm-zOX---Gz9079qsQ-1 X-Mimecast-MFC-AGG-ID: bJ_ivm-zOX---Gz9079qsQ_1773068956 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068956; x=1773673756; 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=myLdHjcUSxsZQ119K7UyROtREAdgOnP5Ymuvm2mislD0Vn5TXtuJhpDPHhNGIj7/lb oGh7i7Zbf/cntirHAtStwF9r7kwkBlWvYWOMPt6QuBmGQSzcKuBpJolWO+Zq6+L5w78t ciBIZQlteQqlhW4Hokn1eTioyo0xtX8ovOmUEhGPRJyidigsGV5oI1m9jfZTbEsAaLGB WiON21tVh0qYSTLoJLIdT/9454qw1z8i6H7MrW+a73gOV9YbEpy4A6lDXyuCNPvFRjYB O5eiEr7ZllAiu7+wUGGbPeKoVESgZgd8GhGGOCt94hVW7PlCW2G84fo1qTLpxBIHhj5O UmBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068956; x=1773673756; 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=b2Xy6JEgEal90aFmFyfHwerne9b/s1pQ9t5QV7omdnosFUd1Npn744On1fDR2TP5+g dENEX3Hrfl7Mou+PqNDdfOLSZVfe/6bKdAb5DH0mdO90bh4Synzy381R1Wg5U1hKNwjx Wef6hhMIMvviuA5tszFba3hf3WcF5UCg6HpDLgFe87GHewetlyee4WH/ixc8s+dd8t5i xW8nsCCBHLDKx70TNjnXu7zCLSoqAXYEO2wzG7tNCRq3n8AZHX7xHbQPsE132D+Sl3Zb kWeRPfXrT2GisMF0tHPAtFCjMV4jyiELOeBxDMLkcRR+QQ7iViJcVYRQxb6E4nglBrz9 f1UA== X-Gm-Message-State: AOJu0Yyu+lzadYeuzs3l2G/ZbzrSVMIGe9BVYG/ewQ998c5fYk9u0wbA nd2MTKaDG4iD3/JeR8xBXgdYlBnXUdzkrNMg+31zM8iERCUML1hK9I1XHK7KH0TZUTS8wZ5eddq B28OGlQD7om4kORcW5DsrH6BcSDngCrRIgZI/xWrCniqyiHOxc9l038Wk X-Gm-Gg: ATEYQzwqGbJDa4t97wsEIDOJKrjkfGEONhqP61rpEjIH+5FEwtGqBzobQzTyOasDD9w HC3L63Mey8wk2I8uMcPjJ/rtDobHdlALyxLcRFCqsLNkwre2lavvtcqmGAyj1PbIxoSM5BBPIea TBD5FnlAc3N+G/Al2l9TTSXA3YlWnx1A8eXIM+LgOCcD+RC7GvMYrPcrep++M5m/DG4DyNAIJkk 8y19s2f+vL3odCE0NaXYgSVA09J4B0R4ACUvvxDJVm65FqN0Mp9Qdn/Jq0IIp8gIFiezc4Ylw2D cs5a4joTdha7SZMh8CyiDQhe74IJ2lORM4nFwnzlxa2dnSyFM2hWP2YluUEUTbusjf7fDjfSS/M NC1dWgL1rkPbvxF4GxDQD8dQRkeZPPnbTBD7Ba1uSRSdSpXaPgPYO8LWFrtaZTg2oWPBSJ9IV2Q Mi4+YR X-Received: by 2002:a05:600c:450b:b0:485:3193:6ddb with SMTP id 5b1f17b1804b1-48531936f91mr112981985e9.3.1773068956124; Mon, 09 Mar 2026 08:09:16 -0700 (PDT) X-Received: by 2002:a05:600c:450b:b0:485:3193:6ddb with SMTP id 5b1f17b1804b1-48531936f91mr112981355e9.3.1773068955627; Mon, 09 Mar 2026 08:09:15 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 04/25] fuse: Explicitly set inode ID to 1 Date: Mon, 9 Mar 2026 16:08:35 +0100 Message-ID: <20260309150856.26800-5-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069090071154100 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 --- 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 Sat Apr 11 21:30:24 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=1773068996; cv=none; d=zohomail.com; s=zohoarc; b=BcZpyMCeDsT7uEGgwEfd9Qx8TLzNNdwRzIHn8l31e78CJL7hIn/gpLDXiOiN1L/RGpxtHkbrdgsYeI1KIRJJXm2N1r54bjfZZE8TQUBybY5rRzaaVfE+ofcOzmlO/kBHhdaviMJKQmdKnv1EmBe1txXiqeCGbelRCS1ab7pd4sA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773068996; 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=K/NOAhtBbcop3vK41eEFC9XhmKIWhMAQHR73Oom/NiTJLosRxUhtIU/CR9/uHdp1JsUgmrqAJNAvR1Ivr5HT9jC0HoPbByiiuCvc5f3ZFJGE/qPjfnWNm2YWbmw3H3IPE7eaZgSaO/edviWC5rl87poSjWgpx6GswxAlReHnmas= 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 1773068996818531.4184127698916; Mon, 9 Mar 2026 08:09:56 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcEW-0000jH-Q5; Mon, 09 Mar 2026 11:09:24 -0400 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 1vzcEV-0000iQ-70 for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:23 -0400 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 1vzcET-0008Kb-LF for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:22 -0400 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-266-yjC4y0fyNcmh6QQ4iHLgdQ-1; Mon, 09 Mar 2026 11:09:19 -0400 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-4836abfc742so100207075e9.0 for ; Mon, 09 Mar 2026 08:09:19 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-485276b7547sm287648645e9.12.2026.03.09.08.09.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068961; 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=IL/NiesQolOZsmjsU/zNXLPbzYT5ocUA+/m0VHpRXrMVlA5zbTTPtAwVJ2iGFCdpSIM7VZ lf+1lRISiElCeLwgxOYLXA2mtCleJtOiqmnOtHrrZg/GYKtSO4g1oij1S393Dak0pwbRbd BVfiRF8PcXUIhPjlTR6QSALa51ORfvU= X-MC-Unique: yjC4y0fyNcmh6QQ4iHLgdQ-1 X-Mimecast-MFC-AGG-ID: yjC4y0fyNcmh6QQ4iHLgdQ_1773068959 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068958; x=1773673758; 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=EE8M+llhI2zbYOtXeKkAif2wwRUKk1aL+TcSKjNVhg7yd29Ojtc/FGonS8cHwiRTf5 fSwBMrKqm8Kal/Yd1O3zZJjfTCVtspQVenx1y5BAY7fj7dI8QdQJcp9Bg68l1Gb5KQDY YiN0q+8TYNfPJeK13buQ6jaTsl9CY41WBkbp/PFZURrK4VRu3lWfwVCq8rXAGf+trmZ3 fvzvC7qTLx9RNuXPbUr5ucsNvdVKEdQVYB1ANcCmMUFItKYtiw7JiZxTpOPzQRJTkoED 1RhUM/d4QurT+b4xVLU20CxaAYHtrq6QjIpFsj3peJrburCE+sfpXbbwwQFO6J/CDyBa xMaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068958; x=1773673758; 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=u+0D8tr8Mxik/OsCeNj5LjyHqmpe6fotbgtmxpLXoGC/7RpdWuuN8eW4FGXyCT49SU hTXatMeSLxzoO5Qi2qJ2mYGt8WJYWUVXet+NiuKVtqZkwVRWw5dhUmHQ9uJe+2pAqdCr ltv7SWYun3S3bEbPUXFFQ1+DKLN2EDwYaSip219jb/ttmdHK3HUGod2vTZN6UbEK+1mJ 6ay8jJ+jw4RY5to5g1niLCjoNqJ93DgKjSTz+xj14N2/1PURCDWWLxATTGhhERT0J3vG eKOJmR3TqrvuZIopcdAW5e0ipMp/ro0j8oap3nyqYwqP4dyXW7dxOsQH49FnD1CITUER Di2g== X-Gm-Message-State: AOJu0YxHxH+h2UpZmN64ErqDe3vNme0Dpv1JtEPo8G2uDPnSpPahUHda YqxUfC3xxUr5ja1+HAzk+NsEPXLFS/qdfhQnvpztGrWjqy49miORUxIuFP1sG32I4fdi7teHhuE WwRTlyllMrW6IVXdGdI0HGR5S/dtQ6LBAugcK4ZNBmF9pl/6xYjXz9F5H X-Gm-Gg: ATEYQzxutyH6m+t2z17Wce5MR3kiTnbDWDA2LZ8lWh9GDJwZ7VxzNAtQM6NXZRe5PW5 Nqrn2F/Y6PJFBIo0SGj/QFLg5iGqZ77+/LiNy7fdmvUsdB15fjt78WRrrHU9L9jw5pBIIkMh+Wj h+S1aa+PcVa2hrFiDs5oCfTOD0meO6xWWc2hGFhudgazA80qBGRMfqwiUFdQh093s+pnjAVd8Hk A7N99W/jSr2YXogrTdH9VqYHq49evH2bj9QKzB1FVmDSewCK+OcW7yB4Szj+vrN9UXy66gUqkje zRhN4H75D4VpStuGUTmKEavMIfZj7r9rzBM6lBaQ+q0faBWlH3aix82a5fkWToWrR43dS4Yu7eS FgoMhfZIWOzPTY39ITSnYMbxfll90gM8+qKbqzRzbWYdX7yo93L1cnFjssLqqnSBKv74b1+VLQk KT/y2n X-Received: by 2002:a05:600c:3114:b0:485:40c6:f516 with SMTP id 5b1f17b1804b1-48540c6f648mr18378885e9.33.1773068958360; Mon, 09 Mar 2026 08:09:18 -0700 (PDT) X-Received: by 2002:a05:600c:3114:b0:485:40c6:f516 with SMTP id 5b1f17b1804b1-48540c6f648mr18378305e9.33.1773068957923; Mon, 09 Mar 2026 08:09:17 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 05/25] fuse: Change setup_... to mount_fuse_export() Date: Mon, 9 Mar 2026 16:08:36 +0100 Message-ID: <20260309150856.26800-6-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773068998639154100 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 --- 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 Sat Apr 11 21:30:24 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=1773069112; cv=none; d=zohomail.com; s=zohoarc; b=efduvpT3orUiBVKeylm4Ymiuquoe+WXr6f1pxiGpUI/5FbzH5fKbgwjK60l3vjdyjt0LxtnDhC3C7Q9g+78lGG6/MuQXp8K5T6lHYPsp4sR7if8il1s+ss0w9chHQcy5gPTRK2H1XCkjTZn70ewsj7mD7TGais3ytPkJncEns1Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069112; 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=NaYaxfHpPAi1kEw1xqp/SOcpgJMjMPgTJ3O/5t99m5h7fzTwB6OUE4TYebjCr55ZXTh3QwsNutcDG/Kr+aifUnGa2i7qbweOWK3V+5kIYw2pRAIM51ZnhG+i9tedX0y6BCfYTqaNd2+cjRJg+hKLGkIrfSuePKZP7wj3zaLxrR8= 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 1773069112348672.3282519420433; Mon, 9 Mar 2026 08:11:52 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcEa-0000lB-2r; Mon, 09 Mar 2026 11:09:28 -0400 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 1vzcEY-0000kE-1W for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:26 -0400 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 1vzcEW-0008L5-Jt for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:25 -0400 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-509-qQSXospPOPWCmwx4aJDLQg-1; Mon, 09 Mar 2026 11:09:22 -0400 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-4837bfcfe0dso138887145e9.1 for ; Mon, 09 Mar 2026 08:09:21 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48539e574b5sm115359235e9.8.2026.03.09.08.09.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068963; 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=OoQmfybZu0K2w4LL0PV6Z1USa8B93MAdKzrk6w2FknzWjeakdtBklWLm8hhmoxXVQJXd6u kYRe6shb2VEzFYhaav7RSAXkHY+RxRKlMYuCZJPgVDbcPFYbLRpx6kgx9pQNz08FejLM0d TgxN6nTQVeZwFqetc/UC+0NYmdySIjs= X-MC-Unique: qQSXospPOPWCmwx4aJDLQg-1 X-Mimecast-MFC-AGG-ID: qQSXospPOPWCmwx4aJDLQg_1773068961 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068960; x=1773673760; 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=Run/GTrkQLrcFZWu5m38+gwOR1xuQCNOfasRafK/Kl+yGVPpPRXoSXhPO2/C5P1d3n FPaxaCjbafJtAPaduxc64CXD3HcWCgLNLKKS7M+D2y4mF6BVCtwTQ1aSJfIcvPF/VCW3 xyUWf05TOfaKPdQP7PncWU6gsWq4H9kE6BEOszM/+Er9NDitGKSIwxHNxYZEvbDdctYX HvBtWgDyFmXqldjSrijpPr0St2yL8/xcTRkDWeitqoolKIjl+Fpx2TLyar42T1Jqi36O qul2RvTf7Dcw54JW/xpUcESOs1ydT5VGnka2jtnw+5KJbZbl968ac8HqeOxiGPR9A5eM zEJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068960; x=1773673760; 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=R1tAGfpDi2TmTUslIuvY9VHaRTkGOMFTqvwDh9uIAHtm+Jfl2Iu30CIN4sRxRQoGtQ uaAo5U+Ug//ro0s4apUyHRxNFqPy3FqDXm5km1jWLdKJh9C8rfLS6GL0GJJxhPTMKODW jJ0ZwEKCy6BkaIqAIrE9bIoOYHQVFTP0Qt9uqxFGGUfu/v3cjyL4WD5JlVQaJ/2GnxTo FGKDyjoENKBLsTNJGhc7W4obP4tBgS1stnfTkc2pwR80eITZCuGn7ChDCRR07I8cRiDu 0AGKfjSj3CqqnVRVf5U6uD+RSF7wf77nwQk1ATUj06tA7hvjiZyn4iyRZFryisVadQ3T ajxQ== X-Gm-Message-State: AOJu0Yw2lTolMaAjokiWITxgC62oxXqkuqPG408gudfE7WvpUxOOkYhZ v4hhDxS6PYAAyjJl178OJ/ujhTE7Y6iZISZEKI7Ueeyq3nilpZaRHrw/+yhJMKODMeOKtt0El0g WsINXV5pM+nJYaELlTvhMFu2EIPGJGfRgjW4rvzp3SyDHitYBsHfuLSSh X-Gm-Gg: ATEYQzyX970/VY6/4H+FNlsvkGfe+j4CPLLJ9UHgTfr22Bf/RhNhsbSSQIb4Mm1bzC4 EoH5mik6oUE7kbuJfFNaSPM0HFuJ8Ccnp8/xdcjLszq2ztB5A29XxdCG68EJHQhwjuU5StoIJnF RkF/l9cYZlg+K1Fuo1JSER7N8lBGqP3vCGr+Oywqg+SrYcNOcN5ah55su+FyQSfD+Ewv+UkG4c1 gSkZdROv8VPMpHolOcIgKLnCzfBk6UNOiOmerD6h1pF7PeYIAlbv4wX2frgsCXmZYvyYTfsyYlA oHh/1F3do06DiLCUTiFLOQU4GsgzeS8JqLJGs8FTIKm6NBPPGC6rVXrS8XIgutUxBnDZlwpGxtC dSJHMjgjws+DiP+rqVquqlRTS1cFzO29x3QGXS7piJeCGtFIekVsF6WgBZ9rfFewj5XMQTpEaE+ DmMn1h X-Received: by 2002:a05:600c:c8f:b0:483:703e:4ad9 with SMTP id 5b1f17b1804b1-4852695b63emr198004375e9.19.1773068960401; Mon, 09 Mar 2026 08:09:20 -0700 (PDT) X-Received: by 2002:a05:600c:c8f:b0:483:703e:4ad9 with SMTP id 5b1f17b1804b1-4852695b63emr198003655e9.19.1773068959920; Mon, 09 Mar 2026 08:09:19 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 06/25] fuse: Destroy session on mount_fuse_export() fail Date: Mon, 9 Mar 2026 16:08:37 +0100 Message-ID: <20260309150856.26800-7-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069113024158500 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 --- 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 Sat Apr 11 21:30:24 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=1773069037; cv=none; d=zohomail.com; s=zohoarc; b=CtgulXQkxRKEJJBcglTHQSaiEQHOYUxsjQvibSiY9dLG9RYLMtujmJ8LoxOqv5n/5xkdhx1mULpCfk8TI7PYGcjcKzf60dKx/558qVCumkE6gfZfkt8ISw7/ckRZl2io/fa0DlDo2vm8eAlq19Sczegcz8rYMCKanvNLjgy6Va0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069037; 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=AjTAaQSicICfePI7g/xK9ptOOj5Iscs1cOcgIpNiDzQ=; b=GqQYXxa7wkdBEx5pNbp6hyMoGO1jtvrcBolec0tWaSjQckiyLK5n+3Lp+Kzv5d/ybfs3ZCMK1ScKkXvlUhcZJ8n6mjsg+dFm+sWjXO16LHSEMHROjorg1gvo6sEc0Azplvl/Bbcvh4R07JAtUNPa4BJAeTQFEd3+OQIbqpZ4wQw= 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 1773069037287305.24823682709064; Mon, 9 Mar 2026 08:10:37 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcEb-0000mU-Ic; Mon, 09 Mar 2026 11:09:29 -0400 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 1vzcEZ-0000kj-Nm for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:27 -0400 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 1vzcEY-0008LE-0J for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:27 -0400 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-428-gvZQ0n7VOYKaZw-cIQr0Vg-1; Mon, 09 Mar 2026 11:09:24 -0400 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-439c12269f3so4037781f8f.3 for ; Mon, 09 Mar 2026 08:09:23 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-439dad8ec97sm29994966f8f.5.2026.03.09.08.09.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068965; 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=AjTAaQSicICfePI7g/xK9ptOOj5Iscs1cOcgIpNiDzQ=; b=MSD4esEVA6HEwGH+0nIXGCsGd213RktvGQGqbGfg2edwxG11rX9gYbAcGtm0HmjAfu6Xr+ H6UgTtv4fI8B7XTFC2iRbSfiLDYDDXql6hQjM8AodDLi9chYpCo15xbn9OzePZsvmZUO6P 5kVI6Yu0utRoFXYGjK+fvFh9HTGysF0= X-MC-Unique: gvZQ0n7VOYKaZw-cIQr0Vg-1 X-Mimecast-MFC-AGG-ID: gvZQ0n7VOYKaZw-cIQr0Vg_1773068963 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068963; x=1773673763; 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=AjTAaQSicICfePI7g/xK9ptOOj5Iscs1cOcgIpNiDzQ=; b=DK/aw4eGuPwq/LFfwEbZD8VqsWW78vDMYMSUVO4WOvYkKqgsDSbyQr6NBY7AxiJLXT 7mZWReDTaJGsM1i4efTSh/7Dml4L319qTOtERCvxRH1IRJNPodjtNux5ZB2QbMkbkECt Pe0H6wZmHsL6BCMnDr22AB0ZIAwUgjC6SDyLCo/a6v2kBz/WsujPjKa2srMzu6dyOf/m t0dHGTIVy7lox/KsTFMkrNsA0y6b2KkshAxTEdVUoI/igQQXcHMJIm1OWhx2l0eENo8F rQxV063RSHwO2Of1QhYpPHwwPaQBU0ZNFeLC99b0xTWjrnrlLrExPc8PSfqrWaSpN0rm pxAw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068963; x=1773673763; 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=AjTAaQSicICfePI7g/xK9ptOOj5Iscs1cOcgIpNiDzQ=; b=qTX8cG0rdWsKScdXy6aIob/ZK3Uc/WBmC86vXgtCEZM2zFzF8hAPMkTTxe5hUNj8g+ ORESwI6qwgT3Y5uiq6HK6NHaSY9VAm0ZZd23wwXR7B8BgFQCX8WVjw3Nj/XEwet0LjKc LGff0jSp/HRny8nDDCyh8KRhpOTLyIsIx/orp/sHHSFk9rH5qIktXbOHVtwp0ExiweIN 6LBaewRsl1XS01Az8jnjW9ZO4346RP/lYMpv50hs7VmQKSGiZckmrkUxqEkDqNr5pacc P1LwmGIzgW5QAUcGJEpFYvJhd5Wpu0wOooab+GOhPRECAdy5Ev3mWEZbuf+Ug/RWTkNV E1lQ== X-Gm-Message-State: AOJu0Yz6rtu73o03S5YpPgi3P65MLWEKilLswsHRIyntI1bCGZR5jljP mw5rV5Rr+Yn2g9y8t1KkwWZAf+hIuxEJxkR+YJiabyVbs1xGYjK4LMP0ED2kKD64C7ljTXA2fZz Eo+iU19O4gAfHQ/vbo8TMVlGfUJHV/XugzIp9xne08YrC9jqZmH37u7JH X-Gm-Gg: ATEYQzyWK9dVNJa2bk6cz154voT7eIKK/rQ6I7WVWL8t8qbURWDBN3DppJ2Wgexa+KR 6L7vDrCRaw73jp+mJeAWzWcoWDbWS+n2MTZ7AEbHo8qO2HQmjMm0JNE5kprO2L+D0H7aUNgt1Ex tecG5psV1SM1EXRFYeRV+1GBdWgirBtGjvgnzmFjjPde6YA6Y4l1GTN1XAgLrTXq3Ar79IOzmxL 0uh0cKHUcPgq8dwW1FxQywK8bIClk8pEH2FD3sHAp9PdG8H+Ttns023GLowK5LO9oRiNyj67Yzb T8xwMe46xA6c0G7j059EjsXHbL2CjzyKofs2ei4S/I/4al9ywQNhEUMWiPWK0hQsutvmWHJJbxz XKu1YpULtSQMu0J44PKfdI6XiCgTBwnTIW7S+RyX2aX7DkRWn03PqSt23FrC0zjSyTUSb/A4/F0 kbnwYL X-Received: by 2002:adf:ff89:0:b0:439:de1d:74c6 with SMTP id ffacd0b85a97d-439de1d76famr14577665f8f.19.1773068962639; Mon, 09 Mar 2026 08:09:22 -0700 (PDT) X-Received: by 2002:adf:ff89:0:b0:439:de1d:74c6 with SMTP id ffacd0b85a97d-439de1d76famr14577594f8f.19.1773068962097; Mon, 09 Mar 2026 08:09:22 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 07/25] fuse: Fix mount options Date: Mon, 9 Mar 2026 16:08:38 +0100 Message-ID: <20260309150856.26800-8-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069038671158500 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. Similarly, in fuse-allow-other, we must now make the export writable to use SETATTR. 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 --- block/export/fuse.c | 14 +++++++++++--- tests/qemu-iotests/308 | 4 ++-- tests/qemu-iotests/308.out | 3 ++- tests/qemu-iotests/tests/fuse-allow-other | 3 ++- tests/qemu-iotests/tests/fuse-allow-other.out | 9 ++++++--- 5 files changed, 23 insertions(+), 10 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', diff --git a/tests/qemu-iotests/tests/fuse-allow-other b/tests/qemu-iotests= /tests/fuse-allow-other index 19f494aefb..eaa39f8f23 100755 --- a/tests/qemu-iotests/tests/fuse-allow-other +++ b/tests/qemu-iotests/tests/fuse-allow-other @@ -101,7 +101,8 @@ run_permission_test() =20 fuse_export_add 'export' \ "'mountpoint': '$EXT_MP', - 'allow-other': '$1'" + 'allow-other': '$1', + 'writable': true" =20 # Should always work echo '(Removing all permissions)' diff --git a/tests/qemu-iotests/tests/fuse-allow-other.out b/tests/qemu-iot= ests/tests/fuse-allow-other.out index 3219fc35e0..62660b40bf 100644 --- a/tests/qemu-iotests/tests/fuse-allow-other.out +++ b/tests/qemu-iotests/tests/fuse-allow-other.out @@ -12,7 +12,8 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D65536 'id': 'export', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/fuse-export', - 'allow-other': 'off' + 'allow-other': 'off', + 'writable': true } } {"return": {}} (Removing all permissions) @@ -41,7 +42,8 @@ stat: cannot statx 'fuse-export': Permission denied 'id': 'export', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/fuse-export', - 'allow-other': 'on' + 'allow-other': 'on', + 'writable': true } } {"return": {}} (Removing all permissions) @@ -68,7 +70,8 @@ Permissions seen by nobody: 440 'id': 'export', 'node-name': 'node-format', 'mountpoint': 'TEST_DIR/fuse-export', - 'allow-other': 'auto' + 'allow-other': 'auto', + 'writable': true } } {"return": {}} (Removing all permissions) --=20 2.53.0 From nobody Sat Apr 11 21:30:24 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=1773069184; cv=none; d=zohomail.com; s=zohoarc; b=CgxY/pLk3BSHeUAGoBCq85xJaIjb4Z0WBDU8qWWS8+puXuxlVtW7OXpnmr+H80AR/f1kBE9uro6Ewml+MWzTYTmDtvewoFgnEFzIlJeLFBSeA9wVuCORQvt2vHyx+lR+bTN/X7GyqT4hrVsbxUT4oTZFkdv9r2ZsSSKVPwdfrQg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069184; 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=fECOYX09fyfbZpZRJ8UAnD2x3KlW1q7/gH1VKPmovhaz0yM3ELj8Z3N1MwSoxP0y6KkxDjamqGH4FnB8Pb3OrYiqaAv2MicDmiLefnSCjKbqbnCx5etS8jIWgPCf8ZAWCKv/18N3P9qST1+WqTYHq7kuZGNrqdtqNRhRQQlJBds= 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 1773069184717270.4888850505798; Mon, 9 Mar 2026 08:13:04 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcEe-0000p7-4A; Mon, 09 Mar 2026 11:09:32 -0400 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 1vzcEc-0000o2-Gb for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:30 -0400 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 1vzcEb-0008Lk-1Y for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:30 -0400 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-451-jVdNCG4rNXeCFXoXdNKd5g-1; Mon, 09 Mar 2026 11:09:27 -0400 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-439c4bde453so4223299f8f.0 for ; Mon, 09 Mar 2026 08:09:27 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-439dae4b860sm29872183f8f.36.2026.03.09.08.09.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068968; 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=EVYi4Svy9V7OQXetFSFJKMY4oKhy+yuuW4myeQnjvL5yvO4qYCuXcooOiJ3bIJCmKX2pTP /XuLcDdt0ABJLeCoX9H4a9q5HjpYu0EVKUlxHpKRwXZdbeQzwYmhiTltzESnDIwSk7BHeD HLCg0rxH1wlW24xC9tUA/2obpfevxVY= X-MC-Unique: jVdNCG4rNXeCFXoXdNKd5g-1 X-Mimecast-MFC-AGG-ID: jVdNCG4rNXeCFXoXdNKd5g_1773068966 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068966; x=1773673766; 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=bp2mx7bBW3FpK27Zjdgv1sczfE9M+K65GLeCCI3B+oNTTvgLSJsRZWWMZ9iqnsyYr0 JeHOdzJa9bE8Nk7N0dqvs1OrUd3xCk8PtOPHfiaWbUDB0x4LoDUcAAHLT2UUz3r3HAdX 9sK4ZP7Gf9NvtVVkc/HRTOLseVONSZshobSfNrL0qEqYykqa5bdT20HPsLJzcIabReyV U5zFPfa45K57EaYV+taAs6/C/BBbaT/v9zaY7NY9LiTQRUCVxIlrFUGHRIn9cT17oOJj PFt1sIsJS3loos/IhYDU0gDLd10vytbqH2zcJ+99e5Mq7mZ5mp7SSVGfMsx46KkyRzQs GX0Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068966; x=1773673766; 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=dS7D/byaWJMD3+Wk71X+z5CFm8+ew1gMjClJBh2osf/omAeveK+fOnBS/kgR1YnPe3 SsVU7V7Mq6sOzgzuPp7fiMEPpgfyX2ETkOSFF5BmYnumAkrRTQ23xQ+D+VRKXfyLHSlJ FHtYj0PAufsi2RJp+VVzNH83LNuNqKe3YcvsBZkxmaAfWAwvD4/WK+hHQSD9c/YKQid1 HcQX6JwDwhTlt4JxguMmPdFzwlGMD3zHNd6BzStI7tMxImPAwotZdaSvmDf2NUnWQXej N2BjVn91NtSaoqKgc6wIe4tkJM4dPSIPGTebwa+znkugMKkCZJwkq/LZZMYse7lIPsX8 y2pQ== X-Gm-Message-State: AOJu0YySdZmfma4Xk1b7t8RLJVfb5wJwnLMPS6SKv218nIqEx1kTfdj4 HZ5IiVgj5hPIQAjtw2u9eJOB5ucLvTu2lfbnU1X9B0I6q7fVHcV+jfG5fIpLnRm0V+ZjUtHUH54 dC2M2D8PIjHlTop5JTV9mFJd5/KlrG8RpyVqJERYRHZTICa24KaCmK+C3RImZLwKW X-Gm-Gg: ATEYQzw9DqtFjBGnLKF/5JTn0sCcWXWpbdKjoXJufIgf/Iydzv5hZWqzUk1Y+196fkD Qy9w92iMUeQL7uq9lLI0H+F4R5StV+VXFqKqeAOYkkJ8As38+ZllkpyMx7XK0AXA+7Q6jmYOkOq jE9QpgqtNS9kxaaRFxVwV68IXNij0HpX9yT7xvINjDNmo2iNBPXZuaofsUr25XvPhX0cNJabuod 9Spa4Nz+qYQZ5hkUHeeSDzPRhoXQUhNl/44IFKyG5p+ef3+2h66kz7xf5jawVE2kE0OdvX7qNT3 PYzkzHVzjhv//QUz1Fhe3FwlpSIcisskqbfY0OlQAn/xk1TxZQkHJa+4wVHVtBMwQF0VROISgGc wKfmE3tJa7ECCHlnyj6FzOwMaNPNc+GhtGUAnMBgdw/lMi0ZfF8FEQqu+9yk1oLeFiKzO5sGEm+ az8jM4 X-Received: by 2002:a05:6000:2211:b0:439:b564:7a71 with SMTP id ffacd0b85a97d-439da64fb62mr19920214f8f.1.1773068965515; Mon, 09 Mar 2026 08:09:25 -0700 (PDT) X-Received: by 2002:a05:6000:2211:b0:439:b564:7a71 with SMTP id ffacd0b85a97d-439da64fb62mr19920141f8f.1.1773068965000; Mon, 09 Mar 2026 08:09:25 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 08/25] fuse: Set direct_io and parallel_direct_writes Date: Mon, 9 Mar 2026 16:08:39 +0100 Message-ID: <20260309150856.26800-9-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069185580154102 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 --- 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 Sat Apr 11 21:30:24 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=1773069175; cv=none; d=zohomail.com; s=zohoarc; b=Y3v6LiDhFottkXkGgxxP8X3CWiULczUOtFYhHPyTdO+4C+OcHZVRnEEl0qvuzAyYso8IbIu9SbUrVdO2nsHiaqD3peZ4WKMb5gW8xPLOH0uE15dw6BO756NvligmiL0zTxIYDAkNERit+kjhUZ7BH3/q5yyy3y1EaunoVR2x/YI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069175; 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=C1peHnlTqwNYg8ZmDDJ67mZrqzdWVkvBcr7u9brO0uA0/AYB/9wKBZDHtL5Bo8aDmWQ/nd9iPNwbtw2P1NGqXr7ARQ0bTrIyO80+cSb0KXRjU17mR+DdQrWhjnYXMahAU3JKq42Vda9Qkkvb8yyj0Z/KTfHjTOGJZ/okbyTvkF8= 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 1773069175728955.6317501026867; Mon, 9 Mar 2026 08:12:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcEh-0000qw-Cw; Mon, 09 Mar 2026 11:09:35 -0400 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 1vzcEf-0000pk-H4 for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:33 -0400 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 1vzcEd-0008MM-Jw for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:33 -0400 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-600-5QBF8yHlNoCSF5dToU7oBg-1; Mon, 09 Mar 2026 11:09:29 -0400 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-4853f33b7dbso5964955e9.3 for ; Mon, 09 Mar 2026 08:09:29 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4851fae00absm345991855e9.4.2026.03.09.08.09.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068971; 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=EwRKwkotEfmgv2X2UuWNe1SPBx9dmQX6TpqOpOLAg/ZjFowi1SGuByhXQS+bU+VC5AbJU2 m7NLib9gOJTyYlIQRbawxoGLyYKcP8UNzZqGYSFXvFG3lzjRpP8TNlmqyUgQO4NDEUsGGB knPNAfJ688ToftvKmkTANjhYzipN70E= X-MC-Unique: 5QBF8yHlNoCSF5dToU7oBg-1 X-Mimecast-MFC-AGG-ID: 5QBF8yHlNoCSF5dToU7oBg_1773068968 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068968; x=1773673768; 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=JIQCkWaXzmhpf/vM3CccmGzbg8IZRJ8xkSz1KBfJGdZp6rBMyYnkTxuii2LBbubudA dJdOxLWZRRCoZqDjZH5H1B5foarKdIJQoYZm1qZyH570ql0TEr7ERK1QZUu+tV40bfdt QOOeeIrOSjJOJSVWl0tR9bRKx/gjJQSlWXAkgEvaTucRE9nCSckqkiYpFcmVxH3mCESr +ntN0DJ2129Wd6esb6Z/ONDBjQz7HEj5wDJmEV3h9kqeEi/kW8MwGUNP1aK6sxcgQlas JIkma26LQpGwjrvMQIdZhfy2pe/YTM1NzM/b5DlqZnULIwklAsXNy0moyCc0d3KT3TEJ wQmg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068968; x=1773673768; 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=TfUnV2YoIwTRnjIvsdQaA0S9NM6vAF4QCrd8OnrXVDo/qKJN8MeAEiscNNt8XypSHm sPChW2v+2idn+nyfgvKNczcktxrwNHu9yMWmxAzivTOoF87DGEfVVJD92msOTaagP3D0 +x1attz8qzSWV0QzHQkpjq1yH+nCbD4EhcpqTo50cMUKwjngurWO8CddhSX7H5J02cId qhv5qc3aAiaq0Mc8+hD56IXL8wnH7V5az8PP+hVzi3HiOq+h4Utz3CwzEoz/fMd0VNEa AsZh3jvF9/gePpBblui/ri30yVtq+OrtVTypx9gg+Pt8CoAxl/3D5yTqKT1KqnjbhKvI 9dUA== X-Gm-Message-State: AOJu0YxJXv+hA4LcOfqI89OPItmaqkwJ/iIVMkyh9c+Evv3ASe59CbHy Qlj8hZPpytrifDUIy0BgGCPrXhftdAVuQTn2O5SR9977ZMVOOGX2MIYcYoAUEONrdLtNBPJkMua qfpPLgK2B2NcClqWuf6tP6HI/ObBlgEVqp1Q+UfWEbNX4G2V9Kq2gA+Z1 X-Gm-Gg: ATEYQzyV76Ouf2NCVDd0P7VD2f0D+Hx8Psu2rTMitZkcFTF3mDb5u1EGh7Ff8tQgIMw iKN9wMOuQLT9rq4YEKbcJI4MNqhOIfprLVIUMFCfNhrT7NJsVT8imwmCrMYdXk6FAENT0SU1jK6 5jnx6bcePmskJQTRnCdrLKoCWMbW3XcX/q/Vk5k1vRz48BxOhDTZCNlmC5gnlbI4MPm0V8R2Nzn XObpkhD+Nvv7IC+tCMa2u2nFUfuMz13MPg2/YYcTdDPYbxqKdh6T/DHxUsBDMha/K3V8STUH6S2 4VYa1/kAbjcLco5cr3WrJn/fYgdstz+GlxXplLG34OWiaq94OvnCJKhDedgDDX0Y8yFOFGHkQlU PWAT3T05W2lwtcoKQFkTsyh7rgL0Vz87ANHPYUhpCPzgMbkdUILHxOU4S40DbouCqXAH096yv8C 2MT0Qq X-Received: by 2002:a05:600c:1d0b:b0:485:4136:99a8 with SMTP id 5b1f17b1804b1-48541369c0cmr8706585e9.22.1773068968106; Mon, 09 Mar 2026 08:09:28 -0700 (PDT) X-Received: by 2002:a05:600c:1d0b:b0:485:4136:99a8 with SMTP id 5b1f17b1804b1-48541369c0cmr8705915e9.22.1773068967670; Mon, 09 Mar 2026 08:09:27 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 09/25] fuse: Introduce fuse_{at,de}tach_handlers() Date: Mon, 9 Mar 2026 16:08:40 +0100 Message-ID: <20260309150856.26800-10-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069177529154100 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 --- 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 Sat Apr 11 21:30:24 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=1773069251; cv=none; d=zohomail.com; s=zohoarc; b=nw5tIFStX4qKzzCEcWRj2uZy5hxZqyb9SsTJ9rAw+v1fP/Yh+76LBbe1jc0dbYosTEm2s0g26ud2ERBfMmtxfxIGjT8bbi+5PSYsgtapPCYA8dUxnnRPquOIOp320MYj7+K4UZUd6G+IMqrfyryFEM4uRxapkzYQNFWukm2m+R8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069251; 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=nhqw13Nlxz9bpbvaN0Vv6B9J2DleNLFWpGme1F3sUpbcBrryEtDMMrkRQngSCyu7n3/wqp2XCju1SK1E2zhCMtJZeOQhTPPD74CIwYesVz4TwMBHrm20bgpDqbSlBLXpzOu04PSu/LWabUFv3Wciv7GRvDPZnm3K2OegHuK2E+E= 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 1773069251204173.70080126848052; Mon, 9 Mar 2026 08:14:11 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcEh-0000r9-NP; Mon, 09 Mar 2026 11:09:35 -0400 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 1vzcEh-0000qh-16 for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:35 -0400 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 1vzcEf-0008Mo-Ie for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:34 -0400 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-381-sJbow0PMMvOnqmY1VYgIaA-1; Mon, 09 Mar 2026 11:09:31 -0400 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-4852ccff333so26570265e9.2 for ; Mon, 09 Mar 2026 08:09:31 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-485237dd017sm92455125e9.2.2026.03.09.08.09.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068972; 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=cnpG1wtwNDrCw7JHSNFCbtJEwb36bS8IjH64cVMmCFaYq1YM/zWZTvi3+nhJfkCwnofsdA TqlpxfCybyaXCbe0Pb5RpmCmeMFlPenV05PR0o5YtFmYiPTf+u7C/A4bgjVNDNIesQox7F I/j/9rtv25n2kE52OBHlfZP8caOlWzU= X-MC-Unique: sJbow0PMMvOnqmY1VYgIaA-1 X-Mimecast-MFC-AGG-ID: sJbow0PMMvOnqmY1VYgIaA_1773068970 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068970; x=1773673770; 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=ncJvgHV/DrYKH5orgzJa2aeQ8YQti+NEZqW+7N0MXSYNrOr/W17Oz13Sl7/qZV0OIW kCmCnQT1M4Y4IjdfWEx1hvZJP6Zoi5G0pkdKCR+zk/OLBZ4ts8ZzHhYJfJ4whaJN1dFa m/IvacTOEULKHyRKOjrOrvyQ7w+SrcmHiqUB21YfxCwUPQllTHR/zlSoHR4KXV535Oc0 zH3efZPGZEiR5b1vP/cskaJ/vPAFM30CeZsiAnctOreOl46Sok93FVcmb5+yDohXexDl BCJf1rN6FaNtexdR87gs+dzKSrszJ6mrm3spvH2n8CYv6AIl+UGvG+2JiREniXLfkyXe z0Zg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068970; x=1773673770; 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=NOPJIWW0qBn6Sj2xWCuvDJRhx0KCp+feNhbIHll6zsb10ZJhV1h6+aFf7LwE7+fbuq C6WIFdqtz2ipYsaVClUTVtdkVMl3bCqw6MqRsHw3GnFzyG5RZ5iORvG9nKdTp1J7w5Le Rj1lxZZwDUeKf4sWTTw4CWAQkwhF/faBE7KGN9RT0erJluRDSZCB0+e7e/jaD3LXZ8FI sUcScwqTz2lvUrc8Wr95a1WmAE1I320TdjfEjHWKLyzQew3arwa3u7jPutlSEMNawAvr aOxKj2DhCbvG7SW82OO6H5MMJtSwri9pypCTi7DgRarZiCJ6Sq66UQZRL31jD+yugoup yRRg== X-Gm-Message-State: AOJu0Ywb4P2v63JDpSmbv0ipXPfJTjS5xpdiFa9ges4UX2hLr6BYee9s 2Supe/3bZJgo2GiXBFTP+BnG4szCxQiFuccifexPldeLjOJ++V5b3e5Z/udhPxQ6HyGXUs/0uCj SJuqmuOFBTX3newovHrU1u2ruZSAz/P4k9uEdB8w3PH9tBeUpXwxy0t0N X-Gm-Gg: ATEYQzzaDTtdxzl75zCxxrDytk3DY78dit2R7zMH/vTXa+KJUnoluyNU+nMpN7zuPYA CFvNol/NPCFeeZBXcSJDhx8Bzqu09ZJMeeAXnfUA6yuzfVeHnnemjtp2s6m5ejpqBHXA91YLVPu JlvmPUIK61xsf8yh37+D0+V/hVAfhoJPPJeOPwnhFQQ8uK0mJWO+AsCzW6+/+4E00OXFO//2og0 NU10x0tdyXmzfAd/EjwvITZtQJvGFq2eud1hvKZCB6HgRvffzHgLjEOm3hXc7nhnBV6Xqm3Lpfu Ek8cQSwDhmZLoF8F6Czf3IB/3+T+q2zrqlBBo0fksD/EU7xpG4qDlqJK8hxPGG8HTWqV/NgZTSE zRptwKVyO4N5fB6MDrmJeMQH2FpIAOUtxXp2TG0tisJo+peUuoH3rxIb1UWxG1kBZM/m2YABqV7 6bd3P6 X-Received: by 2002:a05:600c:1e2a:b0:47e:e57d:404 with SMTP id 5b1f17b1804b1-485269582efmr185943445e9.16.1773068970327; Mon, 09 Mar 2026 08:09:30 -0700 (PDT) X-Received: by 2002:a05:600c:1e2a:b0:47e:e57d:404 with SMTP id 5b1f17b1804b1-485269582efmr185942935e9.16.1773068969819; Mon, 09 Mar 2026 08:09:29 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 10/25] fuse: Introduce fuse_{inc,dec}_in_flight() Date: Mon, 9 Mar 2026 16:08:41 +0100 Message-ID: <20260309150856.26800-11-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069252622154100 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 --- 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 Sat Apr 11 21:30:24 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=1773069036; cv=none; d=zohomail.com; s=zohoarc; b=Eu2JuWTWisekHqvev8OxF5vGvndgp2C1kNDWYMzksKWv/x6+C0CArRoe07LmWC6uP9v0a/v0hUkR2zDiWIoBn3g15PehBLalscA7uR2M+Pr9/3xfjPgcAviKYq91iQlVmU4qv2gph0JOg30lrVlzstcViDOvQhJnkQ2RM5bRS5g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069036; 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=UHXW7L1GHr8yxo25a3+klTIXSzmJRHq9NqPYub3gKCMUXJaS3cdiQevWPQZfKKpv8ELxNZqoTCYFRfK5FR9jXLRR/tl4iJST9W9qm/DRIvrFr3vxu4IYycw6AlQA8ieikbW0JVToLj7NF8E+vW7VdP2ZJB4vds6OqunCLl4zeXA= 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 1773069036549281.4746768305745; Mon, 9 Mar 2026 08:10:36 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcEk-0000t5-NK; Mon, 09 Mar 2026 11:09:38 -0400 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 1vzcEj-0000sN-Ko for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:37 -0400 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 1vzcEi-0008NX-5k for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:37 -0400 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-142-m9fzkmZONp6jbylB1WExnQ-1; Mon, 09 Mar 2026 11:09:34 -0400 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-4837bfcfe0dso138889525e9.1 for ; Mon, 09 Mar 2026 08:09:34 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4853c784813sm63858295e9.5.2026.03.09.08.09.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068975; 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=cSjpR5YT53tT0T4RVWi/GPDjzvwZZMtXREbX40Cpq4cPwfln4mRWZbvlYY65Qx4kodoJSm ZSmOAYs6tnGQ6XnuDWg8ApK6LQ5lXh8gFuRzzHvKk+iXT7promK5MWYOEVq+CspNgTCGdk 0yBvUkN1CAPZEVzMAPIFE+q7sVWgQNM= X-MC-Unique: m9fzkmZONp6jbylB1WExnQ-1 X-Mimecast-MFC-AGG-ID: m9fzkmZONp6jbylB1WExnQ_1773068973 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068973; x=1773673773; 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=AS0WBVDWJDL8uBkiWaDVuGXwk6J09GKnnFqaKxB6M6fMuOYccsEc720/SSzHnY983V TC6AiDPBhIh19g8EZ5N1Qswy80f9ac1qCjpqot5DxCD25PKk2UO5ZzOPmABmu9f0t6lr 7t8MY3yAwB5tXSoR675Xo8s9EQZZ+Xhu/sT3BogPfINy9v48E21vv3sF+Q6Agqdp6sqd RrxzjddOqVITKqJSXexH1N5sp37XCKqbQBVph/MJa1bxqBLPBGESC5RPqb63ZJIvTfs7 z1gH8Vi+roG/1J5XkspmZmOlkJTqzgHpKxpVWP8G0LnjkPQKlYJMPp8E475Lsmq687H4 e3NA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068973; x=1773673773; 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=KkNtbjjB6N1Bd/BAaH0F6ZZF2UtkBBKdbqkXVtP6IGSoNvEr6nH+5umFv+3wgqcJO2 VzM8uK2SlWjiPZsUyiKHEIXleTll3W/UVf/SXxvtzXGdeNe8EodJQ2wPWe0/x2qBZiDs OqRZNNQ0fUhzhxQcUdzwj22v6kZ7e+h3kAk9ovUS1nCwHSrp2riJXCjd6F6VuzFAgXEJ 3Zw/QKIHlf50dPrpJPh5TjJMnaiq7HBs2P+E+zvXwsMbGOUa4ReJtZXqO6RNc+ANd8N/ xDcq5LSmnG08SV3YMDu5zW/b+vyeShSBaUzWclMmwdtUUWZHZr2YwIDKPDEp3/5tPbDI 01WA== X-Gm-Message-State: AOJu0YyT0D9LOpq84A4kFJ8PwLYV1a59/l15uAgsdCVSDYXWBDrGN06+ QFK4au+DUvE0Iw8txok9Tdo4MfCCaPqg412w7kX4iC6cHMToOHc5iwTwDhFju8Z+XtQ15tRRj0r /Q6Ms+8tSwHTFgglL0P/hADOkDNAEm8vbQKCAAsTw71OpWSg/3MPE+M1/ X-Gm-Gg: ATEYQzwdpi+fHRoUhW5FXSYcg4y82kwFuyi0naoVkAUH3nzoFdMgyHCuxjwYWUgg0Ar CqQvfKW/y4tyQJeiMCv1HvEUdaevIa7rmWvEDRjgAgUphZeO5/GrFRz1rR9l0CEa/yktqDZSdH7 lqK0a4GFOcU4wedDTchAlh8KbQYnpg14mUTfvhtb+t9qTOY6xXGAvNfV2FSlQ7rivtFZyAsVV++ 0rgxagCDz1hXNYq8ZkKW5V/wc015NHcrLXaOBrJxU74uDW+YviXo3E1R9XbpU5OZaVwfVHetn5V wyop83avAJw5KPvrpjp8j0y059B92mY6b8JXZwD7NyfeePhPHUtGg6Y0aLYaARChlWfb4A7G01o j0Mg5DaH/PYVDSgTqoHNU08yapiFuYDt3X8x5WPGeZ/wd5LRAkskojatsHUZhalW2juqNrWSCF/ 3YCI6n X-Received: by 2002:a05:600c:8219:b0:485:2fd9:3d4a with SMTP id 5b1f17b1804b1-4852fd94025mr124078925e9.22.1773068972965; Mon, 09 Mar 2026 08:09:32 -0700 (PDT) X-Received: by 2002:a05:600c:8219:b0:485:2fd9:3d4a with SMTP id 5b1f17b1804b1-4852fd94025mr124078275e9.22.1773068972488; Mon, 09 Mar 2026 08:09:32 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 11/25] fuse: Add halted flag Date: Mon, 9 Mar 2026 16:08:42 +0100 Message-ID: <20260309150856.26800-12-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069038629158500 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 --- 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 Sat Apr 11 21:30:24 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=1773069018; cv=none; d=zohomail.com; s=zohoarc; b=ARgr5K+GMmaxNnBp3jUByqob/fGiPWDyx92QiY7j1jhKteU5217CIE6wW/euvDl2ZIzy8E0wmiNMAtswwqNVt05QCqAiGYjyceB23jvSABYS/+kP5Sxa0X1NeLQWoxj+5QzZqxNSxNhkeqzrnUPgp4Ent4cW+Ih6rNfhvzeAvGY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069018; 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=QyiHMZt4VvEKF5gnYh7xgLVLYm6n12AP44S78RGvWiUrjRk7EZCNboozhDVClXVqyWJw6x9CXH+G/4I5pwxeiIizJvws1LmeVjMXjotrJ1xTFfBki/4ZlzkcAxlddClXn3vMKI9YjgGfwor11bRyKRuoYTSmC60jIaduSfOG/G0= 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 1773069018819997.9493138459969; Mon, 9 Mar 2026 08:10:18 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcEn-0000v9-R1; Mon, 09 Mar 2026 11:09:41 -0400 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 1vzcEm-0000uN-Cx for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:40 -0400 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 1vzcEk-0008Nn-Sv for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:40 -0400 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-442-mc4QPzySMgCjMhxBjuAyJw-1; Mon, 09 Mar 2026 11:09:36 -0400 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-4853efceaddso5827625e9.3 for ; Mon, 09 Mar 2026 08:09:36 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48527686bcesm438544095e9.7.2026.03.09.08.09.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068978; 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=L8NMoio9Qk+EXg8vwBrpCuh2F/lfaDlF4rCFCaD2KjgXspX9BFfv16O20+5tmWuod2yAbc blp/sqNv0zCogXaGU+0c280GTVyRqf+F1k+7fLl++Gxll30ICTkjmulUMkFRNo0iEexaO/ Dk0F6B7v2umqQdY2ilWzM0dV3s0SQkY= X-MC-Unique: mc4QPzySMgCjMhxBjuAyJw-1 X-Mimecast-MFC-AGG-ID: mc4QPzySMgCjMhxBjuAyJw_1773068976 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068975; x=1773673775; 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=paClcC0Hs5o1TFteSGe7pOd+UE6hUmmhbVERTvMZ1YrwWbKNnUkPHLHLS1CW9arDhy W9nUEWrs5JBt36k4TfWoo7KUR1x1BEX8zRvJergUQzCMaCuqIZMa8Y0B0k23tWNAHWkn xgvrQMBiK8bFNbn7C7ZnzR0yZ3+zS4CbMMjUbn6p4XfXCyVQLAkvSy7o6/+KqbhPjvZE IglWvNEoYDf5EwkPtuKr2FVe8ZFLZLL6Bwdl7GhPQClpbyG+KOjmvQdedba+kIJ2Eiej x1rL1js1gSWID68kS4ttO5COcVvnltr12gqrENSWOqHv0z/XfIay78jzV7NPriI9vJ5I mh7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068975; x=1773673775; 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=obKMvYlw4atwlwd1opjGJlKqXx/g/u0YaN/vsiEq7PtuLafB4Gynh8JYUgHTSSHQqJ 2eQvsnz6w9UVHcacM77O6J4tBuSTAz7f9KmQp8VOVBkQ0OAAVfpa5qz6iKka0Rs1KLI8 ymCnBkdtwAJky60UyebRAeV+SZaFmp3ucuwhfyQifb6OSGxzvD0A3K8MTw+Adhslc/4h eMjqKu0daLFKXxZJVwQplenyb2gljsvPVQnV0loB8Lwgey9N9whJzN5O9GEbFzccInOh 86ywG2zxY0CrpHAZvIV5giFiDB2BxKB3NlKSl23w5QnGEujTKeiLEheKcJf83OqJqABz 4lKg== X-Gm-Message-State: AOJu0YywJbcS2BUi6aJ2k1tTbDvQuDrxF0MxXQlj0eAvDBoGSAUcegfn PxiX9djriEOWRAnJgiNOzl7grIsHqjzeKMaOFeM6VHwEmtcLTd5W2mXpj4gih1SOwNvhplnugZX dU2WAhod2QTB9P84HUQggsiQklbbF5iSHE4fYAHgn0VTnaB87nGz0iIDT/O0Ky95I X-Gm-Gg: ATEYQzxZye8rii/I4KGm6iJ6HQladt4qjgimnGcXwnWFCptQLPsqZBZWQ14FjC6McUJ Rv939+HwrGjUYugiN536CSAaePc4n00Cj1xE9In5EbHH/rkPnrIthbw/4mKu8rMYvKnQEg/zrZX UQpVimfwOc4H4Jgxs5D6j+rOXQRD18IhJ0GEGrr2eHew1oB68k6J0p9uabMzlZdMpH0GeT5O4Hx Q/cy/z8kBzaZh5VU+swijgRlbCJXsuaRVoSjt4zbiD+1F/19qyGSXnTYuLhmYhzTHcf6qqNut8L iKHnjMG+XONUTeiedpEBD/ZepiP8ON7Eb+b1v+YlO/hX0JZhfBetfB+/RP5k+mk10pEU8slOasc ixs+zcgABvzbSXXWBhzcOzFhnvxYo4nsOkrguEq8CHGYeovv005v/vBpZ0tgyYrjihacjk8ob4U MpYqg0 X-Received: by 2002:a05:600c:1382:b0:485:3423:727c with SMTP id 5b1f17b1804b1-4853423748fmr106722855e9.18.1773068975167; Mon, 09 Mar 2026 08:09:35 -0700 (PDT) X-Received: by 2002:a05:600c:1382:b0:485:3423:727c with SMTP id 5b1f17b1804b1-4853423748fmr106722175e9.18.1773068974673; Mon, 09 Mar 2026 08:09:34 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 12/25] fuse: fuse_{read,write}: Rename length to blk_len Date: Mon, 9 Mar 2026 16:08:43 +0100 Message-ID: <20260309150856.26800-13-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069020555158500 Content-Type: text/plain; charset="utf-8" The term "length" is ambiguous, use "blk_len" instead to be clear. Signed-off-by: Hanna Czenczek --- 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 Sat Apr 11 21:30:24 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=1773069097; cv=none; d=zohomail.com; s=zohoarc; b=bJE+lj6bCUA+HnKQ/HFEAhq2isZuCS8fhXxr3/ZMhTuy1maoYzi/WB1M4kW6GyMjsoy3RAV5673S7ispPVwzKe3azudfWpCNHbpS7hyukCVf18l2m/Q3DomKv198TyRSCSuPoJm7Aq+E0CenTIA13QJ1/VmUUPkZG5lvBqpULXg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069097; 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=hsfu6rrCK72bbvTgjAxPsvIjFo3W8Q3suh1e4WgI2Vmqk6qpmTuT/P6TH8s0fhf1s4RVghateSCUuSg4Mi+QvrU4q47Xgn673rMUna2OvbpQvz+srv2TvdmrMFK6noeoZgXBDeVkTw/30/T3cSYdrxC9zcMgOlwRWOr3mXuITaw= 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 1773069097797194.78382321033962; Mon, 9 Mar 2026 08:11:37 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcEp-0000wW-CD; Mon, 09 Mar 2026 11:09:43 -0400 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 1vzcEn-0000vO-Vm for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:42 -0400 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 1vzcEm-0008OD-Gh for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:41 -0400 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-117-hJOrwry0OPe7IlbuoYOlyA-1; Mon, 09 Mar 2026 11:09:38 -0400 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-485345e2fdfso8767275e9.2 for ; Mon, 09 Mar 2026 08:09:38 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-485237dcf04sm136917715e9.1.2026.03.09.08.09.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068979; 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=Gw1piys7nKQbgZojoiEtsFXHBm50b82yBv0QDLccOp+npE2h6qSnuOUNrVj6eCgrQsfka1 8Q27cUh4wwBOrwTtJbRxiY91/6DD7dRUgbpTn08/z3uqWbld9hZmbz+SjRZrQl6TiAfr9+ IsfZgsgtP84sCpB3GrvR/oNKW84rZHw= X-MC-Unique: hJOrwry0OPe7IlbuoYOlyA-1 X-Mimecast-MFC-AGG-ID: hJOrwry0OPe7IlbuoYOlyA_1773068977 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068977; x=1773673777; 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=MAfixMQHIXD7OxjRSifk9/VQUvq5/Kt4yfewoHdAQqu28fRzDIoK3+jRpqpkQ24Qiv rB/4zV3lOv5+1FGX/zMkypVZkMlkx5oAnmxnSytWMkeUnU7kAin9klmm83PwUF1alJKY TidKoTMgH7Pm4sQDug1NohMi8Izk5M725G02Ew49UozTjPLx0RdRgdEMGkMzeFn2Qpy4 aOQu+EvP8Ip1h8K13opmDFLx0klS6JzwKpn9ex/dQYb76aO+PAENgKhJsg5WFXF/eEtc 5+xlKpqKO7FKgn3HBNg//xdehskJdnBcRXMcKVY94Prz+0Soir2fONu5lW3GP53OtAip IIlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068977; x=1773673777; 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=GeBYKLLHghYuklij4NXQVCO6zF5obXwvhDOL1iT7wHBffEMuhxGCd5cDFYTkTLypKi DtK988Q2wjfRdbUsAUj+GV35JrvHIuxQ0F94XUUNZhqasOfPixoYP0xXhrikOpWJ8Omu zNLffu/dvA3L1zGHiqRyMtkOqMloCPurUPSlVmmEd9SROcpU+n79zDTSK5FeC26a7IYx 3vMm9BfqA0ZqJVgYQAMpkTdYkvnfFMZ/mNzz7fC4hQwHXc+jLIJaYhM07aOLeKUwayht pgjxlSUDEL0/XsYApKC9SJV34qrglVcO5E4p7jgjl6acnw4OYv5N6CQJQF/3I0MfFN+w Nv2Q== X-Gm-Message-State: AOJu0Yy9OVS7pN18JVcNjemYHA0UDkip5oIIG6aLaHuogEQC7uMNJUnQ xUOA+qtXabFFoxAuW6w0GYrUYxWwRHnmiwKmtVEVe+gc3A0At3V9tSlVP8k27YYYYVs1NaFRm9P Pgnk6sgU/Iz8Ln/GypUIXFN0jBM7LwYF1Ar82hmsQ5kmnFdS0bNhUGv0o X-Gm-Gg: ATEYQzwU65Cx7OOhgjporCVCWVfAOQZpZhRmghpBnIwngPGwQx/pIbQcv3vJhN5lrmY dZV17F/mPi+1qyk86Ss9bAxfpzRCOlIu2zFcgCO9nsOSL6hHlJh6QU2waep5iRr7Nbn8bwcw3PI 7P385m91TMZLrPZk7eR6A5f/im0ckcY2eWG+Z+i3HNZ1z7KQUtA3ooPBd9cR6Ut+FPuV5YmJX2s UwRApS0vxyvpY2UpiX58jyeqheXUdmdaP7ijWNbNyDX2Ub/cvi+MFOrm6elSagaOkRTXyEuKWak ILYjNBem63Izmwsn30eH5PjEqhR+Ss/le23GITOVPYU3YUfHdP0tU/Y3PVFfU3f4ngskY1PWlau 5ZewGA6GaOeYAtqOLsonW9INRmb4L9LSYBDC6XjyNps0Y4HRsclWL1I+n4Ut83m1ppYtlUQCEUj gygIGu X-Received: by 2002:a05:600c:46cb:b0:485:3dfc:57c with SMTP id 5b1f17b1804b1-4853dfc073cmr38304605e9.21.1773068977288; Mon, 09 Mar 2026 08:09:37 -0700 (PDT) X-Received: by 2002:a05:600c:46cb:b0:485:3dfc:57c with SMTP id 5b1f17b1804b1-4853dfc073cmr38304045e9.21.1773068976807; Mon, 09 Mar 2026 08:09:36 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 13/25] iotests/308: Use conv=notrunc to test growability Date: Mon, 9 Mar 2026 16:08:44 +0100 Message-ID: <20260309150856.26800-14-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069098973158500 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 --- 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 Sat Apr 11 21:30:24 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=1773069166; cv=none; d=zohomail.com; s=zohoarc; b=CyhjKI1aTMiXDMO05uKhKIXx1xv/3950nhczkEKUWtNqlVVgsnXzPHFAZJz53/G0kPZv1ZzXcVhu7g0cAD12+puahY+URilf253H5HwFsK6rEHaCkWPaxyh8JTfolOyOxzZRAt2DXg3uXX91OaqluwlWpdgj3gHZPy/Ue2qwurw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069166; 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=F5TcBDsTXXcsI1IagYkMItyUZxGpmCbmvohiRUjnMQLQXjS7BehvC6rAzGUBsCc3pZ1c7+IP1Jnf1YwnGYdBf49tq8ShugNlYrYSkZEMSNQd3vXg5ca5kZaCjGZ7JN9T4SJ3d/8ka7Ky7wp4m1Dkxx27WULZATmjNH03vhd45H4= 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 1773069165803439.8974838200601; Mon, 9 Mar 2026 08:12:45 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcGQ-0003hx-UX; Mon, 09 Mar 2026 11:11:23 -0400 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 1vzcFw-0002a6-8A for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:11:01 -0400 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 1vzcFs-0000eL-QO for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:10:51 -0400 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-551-px5IgLSrOd28LXE7ZQ8ZJA-1; Mon, 09 Mar 2026 11:09:51 -0400 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-439b8bc43aeso6177754f8f.1 for ; Mon, 09 Mar 2026 08:09:45 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-439dae2b9ccsm26660513f8f.19.2026.03.09.08.09.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773069046; 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=cSXhqxV5fQN6PZeWolSQX3H4rUw9N2k3xETYS2uqBsF/8iY30fHw9oYziDnhbrX3ugee4x IG4SBy7ZDT33UkgaFz1Ce3yyN6NvKYpa1/l1JubiN3fDXG9akuuNHBgE05c6YFw232LEj/ qQQ5R0E2qJfGu9/H8IeFeXocbBR3bi0= X-MC-Unique: px5IgLSrOd28LXE7ZQ8ZJA-1 X-Mimecast-MFC-AGG-ID: px5IgLSrOd28LXE7ZQ8ZJA_1773068980 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068980; x=1773673780; 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=pruVwzsfpt0ocUUj6JSMyGQcMogrI4X8V109wSLuzq6PRT+NaGcnPx9/sDK8ZGvSfg ueNrdt73h4zo+ckdC9PtHl34PuTDX9d/8hM6OfWNMqfCrja6AAIE/H1RhV2L1RJN42K1 mRpHTufleMXZXADSw8lXVXcwXbkbH3Wh5ADqz+vL+eChr+gfuP0iDOeHcpuklP9reNBs jmVN/Km6ZbIQi3anNIZTBDYJkGo2Or1sKrPYc2PlWuPd0ZVIzk7lWzq2WFsJ2/HE73wE RMfJK7pL8bfx+RzN1OHg7RG526fviJPGJVWAJzFvu4qElOp5LLhIi8ZSTnjbhkz2/oad f1Qg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068980; x=1773673780; 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=jwrtW3YNFlSB6GoLiOF3w+fueSD5WS+7lZK87/BlR7oU9LhTBPzwjItiHnvKMlyAyu lr6zCqa6/b3XN0+mMBvF7NeN1VAdXm3guR1FaLAJRW7jSXmr78fGLGaHz/xd3UnNoWTc tNEENJ/ZT/lkcGJ7e4L+hUGRBFb0gmIikTtkpdtCo5MntLIA8Lrj9U4eEfDHHLsstAnn K3ds4bOE/91JySy+ql20FJW17Yzn9KsGda4NVRnsCo+LVpOKzma04vbt8w3HXQRKe1FJ 61eF2kxwDTFfEDM5HXsd/WP/tMcc6m6eoI7qMXHJKONneRi5LIhnFfTrCQJU/A2CC8Mf I96A== X-Gm-Message-State: AOJu0Yw1Vx9GQcju60n/kXo2qhyeMIQHyVg6ub+GQRkJaNB5U9Ogg5Pl GBsgBonp3pCM+5MGAvomY7wooChkGUh9TemxLxsXNRSOLbOLdhPlCHhdx3ywlyoiHGqkkY8clVt JBGGeXl8S+i/JEJj8rJGD1ar+c7BESlUWDpdkvXW06Pos86DjBM6s1xZz X-Gm-Gg: ATEYQzxP1ODnUGRtC+WlFuVv6bn2yu47oVNGvMsa0JEEad7Pn7tO24RCrZeqhG0wBt2 2ruYcH9x0xez87zM/H6NJzfPp03rDPV3+Tx0LbLZR7pgDOsk7QTz6SXWp0U7gr8Bid2MmgkCvJK UHWYLuPZgRK97Fg8wLHYCeM/nebcBWk6fjeLCoGWMwHevqgnB4jBZgten3fiS5FqsfK6J6J/2Pc 2Y728AEUykhlz0oRxc9UJsIMaDyxCgyVu4Xd8Q3VHlseAyUeNXmBH7bYy6ebDuY6R3cQ16QXkto 9Dkyq6b1UJdgP1qzkgzwr9uOavsyWZ+6NUV2hLicWebdtAwV4okQnINawM5xvw+41nVuRKvhtdG VkOl5rSQ+2pAC1JwNJ82hcZQYzynkKrVMD6C5Y1o3ZAH5NWaFlSAN1Q0PJH2KT07MCHrNEJ3Jp6 IIm/KQ X-Received: by 2002:a05:6000:1846:b0:439:b7b5:b1d1 with SMTP id ffacd0b85a97d-439da65d6e4mr20726829f8f.18.1773068979334; Mon, 09 Mar 2026 08:09:39 -0700 (PDT) X-Received: by 2002:a05:6000:1846:b0:439:b7b5:b1d1 with SMTP id ffacd0b85a97d-439da65d6e4mr20726745f8f.18.1773068978790; Mon, 09 Mar 2026 08:09:38 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 14/25] fuse: Explicitly handle non-grow post-EOF accesses Date: Mon, 9 Mar 2026 16:08:45 +0100 Message-ID: <20260309150856.26800-15-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069169454158500 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 --- 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 Sat Apr 11 21:30:24 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=1773069252; cv=none; d=zohomail.com; s=zohoarc; b=I/MwNJvHwUU8jLcSOcBQnSecwxon3tZ9DBXz5Tt+TBQLOJReL1iXy96tDOtc/04v9c+wX0GFQVGrpP7PHI9fyX1JZYT+KTYyuUm3gg5ywZSsIvL0JfWMZ6iTIpS2an7VG5SpWtOgGq9h4hTaBFk4MLtGZYqY81VXEppnsz0mJbs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069252; 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=NpVDpIlhiBhgzXe6t2/nak7WBsWyLLhtTJx2EzWwwvjWWYxUhuEjcYVTCeDoW3904SEOFSoYcXpEHwvW0UlFPlKmwzvraGn3nRQ442zzMJ5hKzK4wmsovGbGdYsY1tuoWxEefQLr4Z8mAjmNxM+uw47WuFOIUv/J+XQjDgT8sZ4= 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 1773069252156508.3702627197672; Mon, 9 Mar 2026 08:14:12 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcEu-00012O-9A; Mon, 09 Mar 2026 11:09:48 -0400 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 1vzcEs-00011T-DZ for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:46 -0400 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 1vzcEq-0008PL-Pf for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:46 -0400 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-610-LupnWIeUN--q_pRA87t46g-1; Mon, 09 Mar 2026 11:09:43 -0400 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-439da07c5bfso2601790f8f.1 for ; Mon, 09 Mar 2026 08:09:42 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-439dae2bdf8sm28465745f8f.25.2026.03.09.08.09.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068984; 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=fLQ+GQplGHP3p6Z7uGoI2IVgV6LJ9xw/+0vhgAnHbMmFHRmig7sO28ycfJ05LQcBGWO8AR /6qPcLYnBOOim9OX3Zk6N7kyj+HzmCxzP+qzXrvuzz+SwLwHvLosTNu5+43tky6CTGXTKV rUmPTxi+VqdIdRkTXxEmpYwsa4Fhbbk= X-MC-Unique: LupnWIeUN--q_pRA87t46g-1 X-Mimecast-MFC-AGG-ID: LupnWIeUN--q_pRA87t46g_1773068982 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068982; x=1773673782; 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=DpgqGevAQ0PGt1RAw82xCF0+fPv/P4k5cA+GhhoBsVNUBKein3yG6LVWGw5yrnu2WZ WlJp4CegF0eYa4dD/fL4avihMfY0yZX7nNpn3JMa2QZMVRc154cHGOM1lqhK8HRc2gAE vERUk/D7lCNzPtxDs2PAsDtbwmh273BDGTCKtXcO7meaCHFWm5LvXEBxmyBcz6SiQL0n mLOxljMbCxgFViZSPiA/NM/TxsIFycL+v74JhhoeDuUMU9+M92esbgQX2D011Q5Cqn8Z kxMz40spugBIS8GdLz71jpcQaTmIsMOxFzi6gFJAyQdMHdTFQLKyxKjXwfzdzaiu5feg mUww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068982; x=1773673782; 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=t5QmIXarkuS7KBdONd+JJSQkD2FA2Su9qrwYKUzDdrA4iwFQNcHwtBj0DJDOrj+s4V MyIJRnRiTmdeGjCGYZagD+oPXhLCk36tCYZGibrVgnBOUpPbuFK5wCQHztkuKrx8So/p gAwuPlN6p+uOqqpTtA3GJ6rv3rVmgbNn5Nd8lZiQzVDVcUNKscltJGOhQ8rYRl4Yir5W XlN1tTQTg1hlFtBI/993NtX5AFRwJJ2V66K1mBCcrsJYedPD/r1lWJsOrWmoF9wzLB20 B1ZSliaCd3t1BXo5KWcUjp/bVyIJfrrs8odU/q78qvqlaEA79dqdaabZYnXn+w98vaUV t5SQ== X-Gm-Message-State: AOJu0YwdlNNcNRt8jTJPljZEjJAVxT/p7cImnJ6HzcZ971gUdQfJtijS LK8EQOgSjhs7CRlI1+xOM1ab1O3CPdB2O3ZZgK5mA7Fj3rXAdYO4PIcj6ItpEXLztWROXCrFnVX d1TwnLS1gcqkPFa6SRyTYK8fP1TmEPlevYDeYLXFKReq9TqbVIGHy3X8Q X-Gm-Gg: ATEYQzxzaC81lGVrCTTreUdCxgd1iylY1wUVxW2KHF3WT4WIyLe06/TX9NL9F0OLPYX xpRMs10foC6jtHtMJ85toGf2JTefd+gSKrVJRqBh9FH9s0Co2Nbqi4CrWSVNxRGFa9sa9VjR/x8 iM6SKMoaYAnYllSheI8rddT8WBEId4ZjI4uwmQiSp74LvOrNfCcCLLhgyLTAPIYJuNFDiyqtGrT 2Iy1jFs2NLY2TeuIneB0QDvqvBQs16YbF9tMSuntz58MQTaWXYD7l58XTvbZvHFOTX8fBUcLcZZ rjefZhC4gb9GlebkDlRPQMOnvqTg/P0I8Txi3B1gX/eAO+prwKcJkD8Umz+xGTu61gHcge2qGkt ITMVCY2XRNrcPQeBN6dS2j6TglLLUHK6sL6ePuck8LEAEVKczowDMNrbhk7RSmoVGloEP2bF2SO /FzlFl X-Received: by 2002:a05:6000:400e:b0:437:745f:a6b8 with SMTP id ffacd0b85a97d-439da34819dmr18284675f8f.9.1773068981730; Mon, 09 Mar 2026 08:09:41 -0700 (PDT) X-Received: by 2002:a05:6000:400e:b0:437:745f:a6b8 with SMTP id ffacd0b85a97d-439da34819dmr18284621f8f.9.1773068981183; Mon, 09 Mar 2026 08:09:41 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 15/25] block: Move qemu_fcntl_addfl() into osdep.c Date: Mon, 9 Mar 2026 16:08:46 +0100 Message-ID: <20260309150856.26800-16-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069254006158501 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 --- 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 Sat Apr 11 21:30:24 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=1773069069; cv=none; d=zohomail.com; s=zohoarc; b=FmwpDEIJVnRyXj0wOcbisDH4AkRdT4sXytF52R9x9pcYfOK8sziZhdbT5H2oI8y5iYpCA0cMjNmf7LP3z9mFcG6Zc7pk+4OOM8SANsDljoX+87KbHi3AaQmxx+9qN+qSJb7Y1ABzU+wZ7eQKKOQAVxQH0x7PTqXa+AHZEFBKS+s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069069; 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=6mEiC7wHSRQEMHrBtID2dzu9OQQrbDbRtARSqIO9BMw=; b=GC8pgNsoHE8wI9jh6EYjU6LusMbBMNxm973dtAoPdnLoTvO+McsTWvcgwmQWi8i3e9Mg/eK37nnU3dZ4P5kHG3pfgmPxHN20G536BkXIGtMfD+Q88FUwyaOqzMoWgJYh+zn3pJtzGmhtshfwRV9pG40hV4fd69aL6TGXlRmnK/I= 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 1773069069582439.6118237193921; Mon, 9 Mar 2026 08:11:09 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcEv-000140-Ve; Mon, 09 Mar 2026 11:09:50 -0400 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 1vzcEu-00012a-GX for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:48 -0400 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 1vzcEt-0008Q5-1j for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:48 -0400 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-615-hObVzkqnNnqAOeYLtnvEKg-1; Mon, 09 Mar 2026 11:09:45 -0400 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-4837b6f6b93so94347935e9.3 for ; Mon, 09 Mar 2026 08:09:45 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4853252cae1sm173654115e9.3.2026.03.09.08.09.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068986; 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=6mEiC7wHSRQEMHrBtID2dzu9OQQrbDbRtARSqIO9BMw=; b=H86WnRI+g56/86gurdgTWLRqWH5oWF8Pdq9U2VkH5+WQ2dhodSYlf74PHBxzKFcN67wU8D 1jKftsvMk6C7OzmiHjBefEmMhKr6gl4Y1Wmmd4vUWC+t/ys/xIbaABmgaM4u2rEsJrZVT6 XBYbtKVJOahVIem2E00k/EVlcRc/xcI= X-MC-Unique: hObVzkqnNnqAOeYLtnvEKg-1 X-Mimecast-MFC-AGG-ID: hObVzkqnNnqAOeYLtnvEKg_1773068984 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068984; x=1773673784; 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=6mEiC7wHSRQEMHrBtID2dzu9OQQrbDbRtARSqIO9BMw=; b=DcM5nxDsYWTTjmX9FfeOTWsTYkpCJhQGrjUyNPRFyGmT3ubeNOCixj/5xlAW9ujHqo yD9hWrpLHwdxJjEj9c5iga7XbIpKCpYBuYHBQtF1p0nVPjGnqOENgZd+iF+WXS7HXEX0 YSrpmZ723Bm485r2XPnhSewXI4vTCglbKo+SMgEjDQ6MRw2p3EHqs2YOlDO1KQxwboOL 9kCP8fZg0pLIxjkvyfvBKkhoZnOaIt2nXqO2216hqJiA5Y7wgDj7PYr3sUFphEFjURSV h1P4CSQePnPpSFR0Ulk/IL5at/zw99oubczj6g3WTTArzTvqG5skU1vCc6IzpLAPsY9b Mpyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068984; x=1773673784; 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=6mEiC7wHSRQEMHrBtID2dzu9OQQrbDbRtARSqIO9BMw=; b=XCSbHyJ5o96lnELMwmRjgiRoBxM9B7LR2JQ9xkxJfjVXeMzgMuvqf6o6fEPAnBLVkg boicGAtARzzlww1a5BdYzUZVjRivfoYR27WAPU64pmI47oZCop75yWgrNwlKjR/rTN57 TmMkqrAj4kXIhyStaz6msCyqtoYrrUcFOet1adXQ2rEiBv7c+juvIYCakVvOQR3lfwmQ 4Ijltd/Y0OctgCnAKuWgRyFcVqaLPZdJMgjpRzBsG15mQaidEP+8urS9Fc53an1TEkQv HpnEytwA3nysZAfa6hhJGrtzM7Q+GpSoVjERET9vZWt07lKYbPFkW6bcyBFbF46v7XrF quvg== X-Gm-Message-State: AOJu0YyuENJrt1DFVpdEOHD1wNw4E4E12ZnIJvRL1gXIJQcl4VqwFVc4 UCLyAKPOWPjhQQ0Af/373eRNnlvXuGsvKV2BOL7poEXaAkFsq8X6SMPGVn9UUR7M53vCLnlGj8K ZogyXoAX0jyHylPZLdny75LWq4iTmSA8PrF7BIWDUmqcCO/h41bzGP33r X-Gm-Gg: ATEYQzw5cTUzp/24nFLFv7kQxP8WVpwKTDK2+z+Hpg9cg0D5FrFveDHrgWjLzxP9pez ugznI3Pa1XDbkdS96xRdVQPIubXFYl4FJ1+tUYRukafty+o1iO9GzLHMZBxreBimpAQmTa69tei uOxOEfLPQWtohLT8yfmTWCmvDvhOBybvBMzmRWvJEGXrv5P5fNiDKQkTNhBLRTCMSco1q4crCw1 7LLtNLKwwZKCTiIPEZlmuwKzOo3sBDgNQuJYIVFW9hsTHZLT29evc5UU5u8lMyoxQOyXQCsheU6 GX/4kyXor3QzZKNT7PM2O4HWcMzDgeeSDWOePhNcspU5vZquKWxS7gn9JcyqFXAVox1PePTYvma JJXG/2nEPuyMrf1xC5wAq1L/yefvGSe1QF+80ApIuhM1dI23QuAkhAN0C6KPzjPkyL7eRMn2bpl 0vo7A0 X-Received: by 2002:a05:600c:540e:b0:485:39d1:b4dd with SMTP id 5b1f17b1804b1-48539d1bb72mr69257195e9.10.1773068983896; Mon, 09 Mar 2026 08:09:43 -0700 (PDT) X-Received: by 2002:a05:600c:540e:b0:485:39d1:b4dd with SMTP id 5b1f17b1804b1-48539d1bb72mr69256465e9.10.1773068983400; Mon, 09 Mar 2026 08:09:43 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 16/25] fuse: Drop permission changes in fuse_do_truncate Date: Mon, 9 Mar 2026 16:08:47 +0100 Message-ID: <20260309150856.26800-17-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069071746154100 Content-Type: text/plain; charset="utf-8" This function is always called with writable =3D=3D true. This makes add_resize_perm always false, and thus we can drop the quite ugly permission-changing code. Signed-off-by: Hanna Czenczek --- block/export/fuse.c | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index af0a8de17b..b7a710c29f 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -503,44 +503,14 @@ static void fuse_getattr(fuse_req_t req, fuse_ino_t i= node, static int fuse_do_truncate(const FuseExport *exp, int64_t size, bool req_zero_write, PreallocMode prealloc) { - uint64_t blk_perm, blk_shared_perm; BdrvRequestFlags truncate_flags =3D 0; - bool add_resize_perm; - int ret, ret_check; - - /* Growable and writable exports have a permanent RESIZE permission */ - add_resize_perm =3D !exp->growable && !exp->writable; =20 if (req_zero_write) { truncate_flags |=3D BDRV_REQ_ZERO_WRITE; } =20 - if (add_resize_perm) { - if (!qemu_in_main_thread()) { - /* Changing permissions like below only works in the main thre= ad */ - return -EPERM; - } - - blk_get_perm(exp->common.blk, &blk_perm, &blk_shared_perm); - - ret =3D blk_set_perm(exp->common.blk, blk_perm | BLK_PERM_RESIZE, - blk_shared_perm, NULL); - if (ret < 0) { - return ret; - } - } - - ret =3D blk_truncate(exp->common.blk, size, true, prealloc, - truncate_flags, NULL); - - if (add_resize_perm) { - /* Must succeed, because we are only giving up the RESIZE permissi= on */ - ret_check =3D blk_set_perm(exp->common.blk, blk_perm, - blk_shared_perm, &error_abort); - assert(ret_check =3D=3D 0); - } - - return ret; + return blk_truncate(exp->common.blk, size, true, prealloc, + truncate_flags, NULL); } =20 /** --=20 2.53.0 From nobody Sat Apr 11 21:30:24 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=1773069251; cv=none; d=zohomail.com; s=zohoarc; b=RD6Cjcs+5nQWpXpLeTmGgKjORCMecl0Z1aGVxwR30nTJUbDTlf9OhM1iMffKlvn87LNzD/s8Q4tOQHzQltL70sQA10XFJ2KAApXzljWosWsgpl7tbvH/V+tMoZvgcVen5hLA2ge1R0KAGct5FUPaQhFrQRzpQ/H3TQT+0vyFXsc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069251; 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=uyGqB2d9AoizMt8YJDttqE3SMUrvwZkTd0VuUDzYTrc=; b=FYa4na3J/BeY9FHS9YAwGSnnFXWJ7Jrf4cyOwaJmhLkMd2zAedRhQoNrILmhpJGIkYJ3VWnE0a3OWop6qCnEKZuUqfx3kLZ8zmIC2SLl5QzjuVxE1XbVRXWGL2YkmeZYkcpCjBhNkLYIdaZ61vCqbrqr/uHKLn11tl8Swc4zemA= 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 1773069251365177.6551067049313; Mon, 9 Mar 2026 08:14:11 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcF4-0001FF-1T; Mon, 09 Mar 2026 11:09:58 -0400 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 1vzcF1-00018H-BC for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:55 -0400 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 1vzcEx-0008R6-Hv for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:55 -0400 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-673-g_Qk_zANPvKWaZW38K0W0A-1; Mon, 09 Mar 2026 11:09:49 -0400 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-485345e2fdfso8768255e9.2 for ; Mon, 09 Mar 2026 08:09:48 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48534fa65a6sm94028075e9.2.2026.03.09.08.09.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068990; 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=uyGqB2d9AoizMt8YJDttqE3SMUrvwZkTd0VuUDzYTrc=; b=XGtGz/+o3Rn7CjZrrweEwo42Tfo/1vp3tdx62Pw8NuQ6ehY8tlerhxtpIhcRgsg9bLkwyP RWXrt9drUrh3cqgb+kJy4x/rs8seNZJiAM3jH+plrMdePWk9T1nPkrTLpVNmLgaYiXwoTi 7ifSjes+fN0sTqqsT+cIhEsS8+5/DPI= X-MC-Unique: g_Qk_zANPvKWaZW38K0W0A-1 X-Mimecast-MFC-AGG-ID: g_Qk_zANPvKWaZW38K0W0A_1773068988 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068988; x=1773673788; 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=uyGqB2d9AoizMt8YJDttqE3SMUrvwZkTd0VuUDzYTrc=; b=pXRD+nSj2C5Jn5NVPsVRxKVI16ZKsqyXiKCXQCaixMCwudkAusfpuLSRlqlmP95QJS vMINIznJu1bgYWCFcfVrtYt/yAvij0NT8UQLLBkH54L24X+urESkai+5cOOWhIT5Qc6F b5vpF87mhTyGBagA42AARxQAN3ZKeLD4EnaKvQ4lAbVoTRRsptx21wQRjb7RLozX0ygb LEyVuLd5qRbYaumAxswCs+4io/HJPv9gvu3ibR40yevDFa6kqta5MHO0XvfMlU7sXkyN gKW7jPXGZSmsXD04Pe2z7g78d8+kXdFe+P/9aXMC+Z04BG8nS3fuSI6KZRyueHQJPggZ kOWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068988; x=1773673788; 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=uyGqB2d9AoizMt8YJDttqE3SMUrvwZkTd0VuUDzYTrc=; b=J+nj1kUB+vUMKFNFJFmrwafIy9XIdsNplWT+wa9lab0n3LqcUfYfYzdKwZf62fgpyv X5Y4XTjTE0i8Qpdlob4fgvTrSbbwhq7lLmCdN79BYrTv1vldLN9p3ai2NnWVKInQLrji SJ/D406dpkkuhiodpodG+afji+ulaAROo1dIwFpHBwltbCmSPZd57S6/dIx7wKP+IW2h 0jidVFrajX65usOPnr/vMG2RCWSes9bCUJQy2I13LTd8uiSuFFIeOsKQnworN/+nhO93 8ykPrfppl8UPbxKoX+ds1zuUnjFVf0hPQ5qh6rJuSmHojO5iZNZBQ4lPqazVxx0mOZDl wDYA== X-Gm-Message-State: AOJu0YxgzxspM0uPHaB+8d9XTEY29ypx0H3hNEJFLlhOVn8yVaBxb1hp VZqbXXmr1XkcLxsyXLSTZVwLugRSAjkNGDZccDjgANeP6IIjY2Baw3Q9PfSGnY/2qAD8TvNhJeR gdU1/TThU4Z/dD5H3649QdUzGQASiyGA/KEvidbFuCa265clJTIXq/kpX X-Gm-Gg: ATEYQzy0nrZZXwx+WwOOAId8Wg8J+wXRxqW44R7efuzedKUuTS2/YxwrBtQ6cOBnmnn 5JU3i8Bns+Du8f6okELsU40TM6LVi4+XQqU5th415jrEShIvHbxxf5JryUu+OsPT0eYEy3kZ0iJ EHXe29xwJBhrfGDEPneuUsnRsVfCH9EkiW+HFPHV3KOMmMU4c4RVCPmZ4H91nfxxzn8bJjijd4s AxnyOBGocSoF0g3vnDEZKJqRZQ+0tMlVgMYm+MykSC7bw9bEbqAXTQvYBOGcOEJ3oi7kJYBpJVt /PNO1fDKH/L8GOi/CXyXGsK06o6aAZqITCBwiqmXok6F3TRrARwL1IGKQ//ja2HNot24eaAEO9r iW+ycYzEA7CcuugSHya+HYEZjOp/QfxNIITMQN2IbVaCmSdupljjqxdw/d7w36tt9IQ7u+CwfDU BllDlz X-Received: by 2002:a05:600c:350e:b0:477:9b35:3e49 with SMTP id 5b1f17b1804b1-48526916bafmr174000085e9.3.1773068986734; Mon, 09 Mar 2026 08:09:46 -0700 (PDT) X-Received: by 2002:a05:600c:350e:b0:477:9b35:3e49 with SMTP id 5b1f17b1804b1-48526916bafmr173999225e9.3.1773068986004; Mon, 09 Mar 2026 08:09:46 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 17/25] fuse: Manually process requests (without libfuse) Date: Mon, 9 Mar 2026 16:08:48 +0100 Message-ID: <20260309150856.26800-18-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069254757154100 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 --- block/export/fuse.c | 945 +++++++++++++++++++++++++++++++++----------- 1 file changed, 721 insertions(+), 224 deletions(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index b7a710c29f..bd099d1291 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,101 @@ #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)) +#define FUSE_MAX_WRITE_BYTES (64 * 1024) + +/* + * 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; =20 +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 +147,8 @@ typedef struct FuseExport { */ bool halted; =20 + int fuse_fd; + char *mountpoint; bool writable; bool growable; @@ -71,20 +160,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 +205,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 +351,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 +389,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 +414,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 +423,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 +448,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); + } + + release_write_data_buffer(exp, &data_buffer); + } =20 -out: + 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 +612,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 +637,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 +679,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 +783,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, @@ -520,101 +823,99 @@ 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. + * Note: If the returned size is 0, *bufptr will be set to NULL. + * 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 /** @@ -623,18 +924,13 @@ 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; + /* Explicitly set to NULL because we return success here */ + *bufptr =3D NULL; + return 0; } =20 if (offset + size > blk_len) { @@ -643,108 +939,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 @@ -756,16 +1040,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 @@ -775,8 +1057,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 { @@ -804,8 +1085,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 @@ -823,44 +1103,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) { @@ -870,8 +1144,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)) { @@ -888,34 +1161,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; @@ -923,21 +1200,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 Sat Apr 11 21:30:24 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=1773069192; cv=none; d=zohomail.com; s=zohoarc; b=aEjVPMsmYdr/4wG7l4mp/Zsrgcqb5TFhUKBxVyDMjIJP8YJAcyPPD198wNRml3kX8PJBeWqnfQkfkrK6XX02qplgLV45rhBrvHViGCtRJedc3QPkcshOn17a1L35XpqJ2rDuviRiX8/2o/Us81rMX+3VrSHNVTYp0hoiQbWPZy0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069192; 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=ri63c0zIoSQgAinKj4Gr9ogtshcXsY80vNDrWEB/NVk=; b=bz5gSoGndi1DFd6H5HZJo8Dljzjd2eEMILPJbxceU8h8x6FqH40YfAWgfCA4ORn2Jftdmbfp3TIXkrippIFHDB+hkCEfhU3r8o26HCMRGHNmeFzVxUbwiq/tCHcc7WUpdmxsOF08U6UWMbAE2ydKdLra73i/Eu9KC3J9DRmwkH8= 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 1773069192583730.0285377737308; Mon, 9 Mar 2026 08:13:12 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcF6-0001Iw-F1; Mon, 09 Mar 2026 11:10:00 -0400 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 1vzcF2-0001DW-Rc for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:56 -0400 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 1vzcEz-0008RT-Ch for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:56 -0400 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-650-GHRI3WG7PdGx1TGdfMrjGQ-1; Mon, 09 Mar 2026 11:09:51 -0400 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-485355493aeso3417015e9.1 for ; Mon, 09 Mar 2026 08:09:50 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48531818b5asm88131615e9.3.2026.03.09.08.09.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068992; 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=ri63c0zIoSQgAinKj4Gr9ogtshcXsY80vNDrWEB/NVk=; b=GDzP8GyANw7jMf9C9+IUshsW2StizenNk5qFoEDgEQmbI1K//dR+9RLVyRfp9pXRvAJRWp 1/VspIQvZxEMo48bRWK4a8tZa8xKkuPzMkZik1OFFPYuH4QHrEYAPCZR3/dGIXqpEAzzBL ki1RIE8uacHideuNKxj/4v12dI1JEfk= X-MC-Unique: GHRI3WG7PdGx1TGdfMrjGQ-1 X-Mimecast-MFC-AGG-ID: GHRI3WG7PdGx1TGdfMrjGQ_1773068990 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068990; x=1773673790; 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=ri63c0zIoSQgAinKj4Gr9ogtshcXsY80vNDrWEB/NVk=; b=gBJINylToqoIein58AZtJD2uY7Mani6ESzz5EDwsObgGBZRt86eazL/z/tmnusRa4r +UgaSI3/H68DwjT/VNTqoX4SAKC0Taf5xCFYe3qpmVoUSx68uDgtpr8SDpjNMBts6eG9 mDUnjcUW0BTCERATb0wmyI6nDFTqHflyKxQbcgjQjGiTQj20+p9C4iMTD7g253TiOhRa xDOWs96TTpbJIL4ppiEJ978zZzqra5a1dO1lXYxOiO9T+vL6IZxewr9wz85bJ+pBwa// R6TQuZo9WCMqPBGNYufp05tUXXzV4ppRKdrkpWW8ZkdLR0fgvrHyct8mhNPNI0TDVKUn 4skQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068990; x=1773673790; 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=ri63c0zIoSQgAinKj4Gr9ogtshcXsY80vNDrWEB/NVk=; b=rrj3BfcyJ594HhVG2PXfEPksm3wv2plsRLutpxiGLEVXa8UMFxsB35eXRvm+XhgjQf YFh318b2H70Ix2kUNECKz0D7cX0N6hSaA0YKaLLM5dgUr04UOC8rLjpyBx/NliBEkBg6 muUWg8mbc6SpLEdhZ+9XfjX0NlhoNSurthqhfrVzeAzAoQMnWT9NTv5oAs8ECLrScrGO op0zNtEouL5SgAWq8KHWBs0pHIt93c/cP5J0aw+cvdIXs8ubeF8K77ZxIy4bspumd6OV NLi7ZHcREDzoDWNAHNGWcxvHAFm7J+NC4iihibtBI/kSRuax8IDh9g17dT1sW/2ENWyY iFDQ== X-Gm-Message-State: AOJu0Yx34nwI08I+AjW7wPD2lx/hut01Z66sp3igp7jLCxGESsfvQ9H6 GtDkesqYKb6ZRsH5rx8FZYBA/lHiLDwpReQ7hC++I69oeBC9pZn0x6rMiyUA/jaGqsbssC9VwCk bqSZ1MLiHhVCItuavWon/8L+RI5aKy858npQ2RkUYlaONEoP2aq07mvwz X-Gm-Gg: ATEYQzzsnE5sZUYhwT2G7mZmho1WO5HCaDDZdTEechOjhoUyhZJrQU1iMn2gB1sVziQ z4q4ekIKnTLgquNMP3tgY3tWpIyBHCBlEbclMN+n0wdZUePJ0R433RTs3wR+3r0eICE2CCj54Cs 3JsMHfJrUIknDNj2Xc6yRo3unSJ/A3+ktZAwXLJwXASR4MJr3xPnYeoFJZtkY0lKx7ECVEP6ByE dMeovdcDgSJeNexbN817P/kfJ8y0Kvz/EvJ7TOl2OePx0JTOJa+wju2xBq71EabNxVR8LrQz3Wi kNF2AhWJeuEksz61OX6Qz9t5ssYOyf/CjFZyFP7u6JRG8Lh8cyUvMx4v9oHeoCUqz4Z+x5YVzoM QkVSpnRYPPy2AfZRyuxs8qamBlvc1CUZlAXqrlCY5oGDxYwRqGnfFhQWXvNdeg8yQcr1ireyU/2 zcqoMw X-Received: by 2002:a05:600c:46c4:b0:485:304a:58cd with SMTP id 5b1f17b1804b1-485304a5a00mr136119535e9.4.1773068989701; Mon, 09 Mar 2026 08:09:49 -0700 (PDT) X-Received: by 2002:a05:600c:46c4:b0:485:304a:58cd with SMTP id 5b1f17b1804b1-485304a5a00mr136118845e9.4.1773068989214; Mon, 09 Mar 2026 08:09:49 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 18/25] fuse: Reduce max read size Date: Mon, 9 Mar 2026 16:08:49 +0100 Message-ID: <20260309150856.26800-19-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069193544158500 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 --- 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 bd099d1291..f32e74f39d 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)) #define FUSE_MAX_WRITE_BYTES (64 * 1024) =20 /* --=20 2.53.0 From nobody Sat Apr 11 21:30:24 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=1773069034; cv=none; d=zohomail.com; s=zohoarc; b=T8nidFCv8PqmshgqSU7+41iwWx+RFpdmJFIM1br0p3A4AIidQo0b3lh2Lq6mNz/D4UeC/vTVmuYzkMFO8t4ir6Lu7G/cNIvRyPr4IdVAzTjCldFkkQLIC48QOFti94GgIrtnPzX+CQmvlrEFs+Yr/bu62a4QWunDyvqYERblffc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069034; 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=bG2Vty+xjS126Z+XVEPqFO6PRk72dSZBpYi3U/L8/2g=; b=i2ga10poXJGIHge2dYvTIpfTdCEW2WKHdS6A+OWRXr3B+gJY8JTs/pr/24M3YRL1L673IyYH1Ri/oN2xChw+Rq0A73DQyN58Xb691HubhVC1PwPkSnMQEVOYlFvSV6pJaaTt7ov7Nwg6BmWC5PpzLgMXE0dlqJryWieJr2cxF2E= 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 1773069034921207.81970328597595; Mon, 9 Mar 2026 08:10:34 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcFB-0001Ou-4U; Mon, 09 Mar 2026 11:10:05 -0400 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 1vzcF4-0001H7-T5 for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:59 -0400 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 1vzcF2-0008Rq-8l for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:09:58 -0400 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-296-O0HDllVuNe6BNFnztsldfQ-1; Mon, 09 Mar 2026 11:09:54 -0400 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-4853b5b0fafso12243035e9.3 for ; Mon, 09 Mar 2026 08:09:54 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4853a946978sm112564855e9.1.2026.03.09.08.09.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068995; 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=bG2Vty+xjS126Z+XVEPqFO6PRk72dSZBpYi3U/L8/2g=; b=ASNMRl9i4coVWpmbsHnm5Ry9BWnOOJVvIJaRN+K8Dt+78rtdWRSkRWdDG3LPdF0s1XwZPX iZQQDUWzd2yvVPau/GIg4jvdssdcpPvWVFQALO7ICk7jh7SgSrBbXbEkeA5Tjo4agcP8Tc zZZNEgfW3QU89zuzQQ+Yggd5GNs8QK8= X-MC-Unique: O0HDllVuNe6BNFnztsldfQ-1 X-Mimecast-MFC-AGG-ID: O0HDllVuNe6BNFnztsldfQ_1773068993 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068992; x=1773673792; 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=bG2Vty+xjS126Z+XVEPqFO6PRk72dSZBpYi3U/L8/2g=; b=A8ypyr58bygB8qbMbC+ANkxQR4+xHodkfXElhyPMTCWriejKBhipey4wTa93YWagSG hLoDVgXo7kpII4HP5Y9ctSttLMhu3xk4rnlEnJGZOvKJsLqOJMw3fLPxTKXiaKQgaJq+ jH+C/jxHVCg8wupCMEZOjZtRWJisyLLon09vNIBfUGTn5X45NQ1X0w9PMhi3am6mTKAA 673dY0GxcqZK/mh3fwE2KSgJVQtJeflV/mvVgNXEana2aPdBr/ugD8n3Ft+JdNHTKeQZ OtrwoYtSehnGBm2z6VjgpxOb4tepntZCKq+LNOCr/CWqNEJo65T+5pbQaD1aHg/sigdM PQFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068992; x=1773673792; 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=bG2Vty+xjS126Z+XVEPqFO6PRk72dSZBpYi3U/L8/2g=; b=i6iYFAG3K6yyWevI7lEfdjX1Gk2j4kuGf+YNLdRT8pz/dJ02eFGL1TdaHAUmBBtQ3T 72ibgjFr5T6befa9KvhVx4c9VTCumlaPGjTzMO27m8zHOOiyjtPyNBC5+bDdMLJcAB3O D+2ATD69ybsfVlvkBPAsu6umtS0cEcDsIwDRxfuub70wTV4xkGCFJu11nD4Ejc69ixpN elB/VgH6/OXsm1chT5FYksHYAAwrlweWXvH3PHKKGaNJDSBu+we2mfK5Xpk2BWxZFPK9 Ij+b+BMMVoox4xKdr2UbP32EZS2g3qBqqfHyxxYKBsn8ZdqeucKydeD+tQQL9C+kGfer mvJw== X-Gm-Message-State: AOJu0Yw6LI0fjPykXwefAzLlnaeGvhxEi4R8ZPby1OSi1hjvFAX8CrnV arfLsJB7cPtqqaujrxPo6bMtw19sVO/Zp+Z5onQE4zK0urMmhdpQ5yXhgn9o7GbuJOWVP9boGdT zqXFx7hiYMYnMidrNEJN3vpWRFfwcStjod1AARaY0n9n//PUvi3Fmva9yuCM2P/H2 X-Gm-Gg: ATEYQzw6tgam/9gWstbSn1XrLd3Gpzkz20ws/TKfvdImFCStTP/nA2sdefcN3jiaIMI sL71MuWF2xFWhd9D34WxxiQRFx9vaIqexh00KvBElwxvv0viqVa2va8MFN8EBh69Sb7vMcGTCcn x1R7KZ36Ftvk+UXdpMMCZJ2bvmn37N7C4/B3Q0kBn8HjWjvrolmb6mTtHOZbsFhG+nbZenuSZ3I FdjdUtYndpd0gyoN4UgBMHdftu2YVRjqBVXCGaYoqRYThXbOmyQh2Q2qM5c6DRObjEHtwgBEHR/ KXFtkxTF7q24FuubSTpj0Zh3KO4GTPSR6a7Tii0LC5JsYiDeOlnXg1UeiPSFC/uMizxkdnP41Zi 9SNZpvqUOdplM3rSUZYchBedOF+wVTzYJDKzowrydmDBcJUNamptp+3v1tZZbljg7hO2dlf7ax9 J1zFxc X-Received: by 2002:a05:600c:4447:b0:485:34b3:8585 with SMTP id 5b1f17b1804b1-48534b38936mr100401765e9.8.1773068992090; Mon, 09 Mar 2026 08:09:52 -0700 (PDT) X-Received: by 2002:a05:600c:4447:b0:485:34b3:8585 with SMTP id 5b1f17b1804b1-48534b38936mr100401115e9.8.1773068991503; Mon, 09 Mar 2026 08:09:51 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 19/25] fuse: Process requests in coroutines Date: Mon, 9 Mar 2026 16:08:50 +0100 Message-ID: <20260309150856.26800-20-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069037510154100 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 --- block/export/fuse.c | 176 ++++++++++++++++++++++++++------------------ 1 file changed, 104 insertions(+), 72 deletions(-) diff --git a/block/export/fuse.c b/block/export/fuse.c index f32e74f39d..7c072409d8 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" @@ -181,9 +182,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) @@ -518,9 +519,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; @@ -531,8 +537,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; } @@ -601,13 +605,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); @@ -682,8 +702,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 GRAPH_RDLOCK +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 @@ -738,7 +759,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 GRAPH_RDLOCK +fuse_co_statfs(FuseExport *exp, struct fuse_statfs_out *out) { BlockDriverState *root_bs; uint32_t opt_transfer =3D 512; @@ -766,17 +788,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 GRAPH_RDLOCK +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 { @@ -803,8 +826,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 GRAPH_RDLOCK +fuse_co_do_truncate(const FuseExport *exp, int64_t size, bool req_zero_wri= te, + PreallocMode prealloc) { BdrvRequestFlags truncate_flags =3D 0; =20 @@ -812,8 +836,8 @@ static int fuse_do_truncate(const FuseExport *exp, int6= 4_t size, truncate_flags |=3D BDRV_REQ_ZERO_WRITE; } =20 - return blk_truncate(exp->common.blk, size, true, prealloc, - truncate_flags, NULL); + return blk_co_truncate(exp->common.blk, size, true, prealloc, + truncate_flags, NULL); } =20 /** @@ -825,9 +849,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 GRAPH_RDLOCK +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; @@ -864,7 +888,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; } @@ -883,7 +907,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 /** @@ -891,7 +915,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 GRAPH_RDLOCK +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, @@ -906,8 +931,8 @@ static ssize_t fuse_open(FuseExport *exp, struct fuse_o= pen_out *out) * Note: If the returned size is 0, *bufptr will be set to NULL. * 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 GRAPH_RDLOCK +fuse_co_read(FuseExport *exp, void **bufptr, uint64_t offset, uint32_t siz= e) { int64_t blk_len; void *buf; @@ -922,7 +947,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; } @@ -942,7 +967,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; @@ -956,8 +981,9 @@ static ssize_t fuse_read(FuseExport *exp, void **bufptr, * 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 GRAPH_RDLOCK +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; @@ -976,7 +1002,7 @@ static ssize_t fuse_write(FuseExport *exp, struct fuse= _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; } @@ -992,7 +1018,8 @@ static ssize_t fuse_write(FuseExport *exp, struct fuse= _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; } @@ -1001,7 +1028,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; } @@ -1016,8 +1043,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 GRAPH_RDLOCK +fuse_co_fallocate(FuseExport *exp, + uint64_t offset, uint64_t length, uint32_t mode) { int64_t blk_len; int ret; @@ -1026,7 +1054,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; } @@ -1045,14 +1073,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) { @@ -1063,8 +1091,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 @@ -1082,8 +1111,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; } @@ -1092,8 +1121,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); @@ -1110,9 +1139,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 GRAPH_RDLOCK fuse_co_fsync(FuseExport *exp) { - return blk_flush(exp->common.blk); + return blk_co_flush(exp->common.blk); } =20 /** @@ -1120,9 +1149,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 GRAPH_RDLOCK fuse_co_flush(FuseExport *exp) { - return blk_flush(exp->common.blk); + return blk_co_flush(exp->common.blk); } =20 #ifdef CONFIG_FUSE_LSEEK @@ -1130,8 +1159,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 GRAPH_RDLOCK +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; @@ -1141,8 +1171,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; } @@ -1159,7 +1189,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; } @@ -1303,18 +1333,20 @@ 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 */ void *out_data_buffer =3D NULL; ssize_t ret; =20 + GRAPH_RDLOCK_GUARD(); + 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: @@ -1322,11 +1354,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: @@ -1343,19 +1375,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 @@ -1373,36 +1405,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 Sat Apr 11 21:30:24 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=1773069141; cv=none; d=zohomail.com; s=zohoarc; b=HL5M017PZ+670jipLSIQ1U/5xNfNjMM+y2F8rxCbnWzSfljvjHDneLPJRf2beGeLA50b0JVTEqPUgUVeHejV+mGsJ+q0vLZebrZgLrWLtXdtjxLeABv81MBz/G9ctvrN3QCG++6QKWpPsmAymSFcJMT3a4unnRyzBdRpaC5CupU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069141; 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=uw9mkIJeAoLcNg5usnHI58+sUR9kWSgvtwa9shmiFV0=; b=jNUCeTerD9pzsQvAROxUNnRt7ZV7qKwwiySeSUbI8Ehq0559ULLd8g00Lmmw6HsdDU/jBaMxeFeAI8bRjqQ2o7O779fa0yi23FFD+CJ9pYREsQUUYim+A+gFsntyes0njMeG7RrN0qF50O1lU9Av73dztHiV8dwQGwJ54A7T+x4= 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 1773069141264959.0511082848075; Mon, 9 Mar 2026 08:12:21 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcFC-0001QC-NQ; Mon, 09 Mar 2026 11:10:09 -0400 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 1vzcF6-0001Kh-Rz for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:10:01 -0400 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 1vzcF4-0008SY-I8 for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:10:00 -0400 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-449-oXVVdURtOHiWyD3Hv9d8vw-1; Mon, 09 Mar 2026 11:09:56 -0400 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-439ca4b3d0bso4278870f8f.3 for ; Mon, 09 Mar 2026 08:09:56 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-439dadb85b8sm27483130f8f.17.2026.03.09.08.09.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773068997; 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=uw9mkIJeAoLcNg5usnHI58+sUR9kWSgvtwa9shmiFV0=; b=TRtwH1qaVwqflUt/vr4yd9YAMj297zdMN9X9Ca7gwZctQGhT6wfSnTld5ASRUSEKJtQ+Gm iF7YpnetlYy6Z+dkRlVA6IORDOfs8rvKpQzZ0rx8ix0QGT2mySFJ1U2d88zs7opoWEnaOb ScPCEa+USEo9IXSEnwOD/sHLGriJD0g= X-MC-Unique: oXVVdURtOHiWyD3Hv9d8vw-1 X-Mimecast-MFC-AGG-ID: oXVVdURtOHiWyD3Hv9d8vw_1773068995 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068995; x=1773673795; 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=uw9mkIJeAoLcNg5usnHI58+sUR9kWSgvtwa9shmiFV0=; b=O94+hobuIHOTwhU49LZLH5h6ZRfNhd2ItabTwenFr3WtXQvnOeSRTJljR7e1aRaGJA NyINH8BHFrzbt59+kTWLhiQagnD0NFgawzxP+uAlNXe+fhZxRuKGefrYZsXNOuhmf59q fPg1DlmXzVA2GY4pHcNZ07mZ/bfhnSCjhTTWdk74GrmcvlqKy5vMO6Cue4FYX9ccwCYv YoJuHyXrqme/6y879PA4SyxLiJorD/HBk4EsRhXixK/lqar/P+zHcJwKl5+JAyv/iFGK EtA74gfoE2qJQbcxZTJyrAx/SEh/4SDyWraZisSlc9PMZGXG2kpOtcFp6YNqG6ypLRKE BJkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068995; x=1773673795; 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=uw9mkIJeAoLcNg5usnHI58+sUR9kWSgvtwa9shmiFV0=; b=KdsJyO1DPIrdyKp6CkvPNYjiG1mrxzToRjhQwBL6YarF8WfJggwFg+AArtSW/uwP7l ujPQuiyiVt5uIp8m7UJeq4Wq03wgbTlw+rBoRraohKQ3dt1IMWAwa7S6RudM++2viP/5 WpIgQOng3mU1WPxuDsKTLrax01Ud7do0/GZiUyBbhTdIxMOcWM+ors93NT53P5aJkyBd wJfABok99ekpgvSJSk9bI491bZVgLNQnvZ5Rqze3xlKvKwndqyYD3mkJvwO4ZToZxshN /76n/72de4hF17aBEJk5DkMHwZANaDSy4GtnXzdTbeIct1De5rJ8ciIK2ddCEqAXwFsi 4WOQ== X-Gm-Message-State: AOJu0Yw3x0BlCoQSnAa4AKFMQWNzbPLOlZUE89aeia6wrc2+mmxzh2kk ij06rOnVdQcQEobRSC1IXwo6+aVL4FQNXnXeX5iCoKp3lj7l8icH4Td3BOVLtZtnyRGHO/FtU5S dW8x5BRyofp5Xi20NT8fE2XONqE0gJR3uh8sVOmMgBBseX8yqlGei0S5Q X-Gm-Gg: ATEYQzxU/IvmHTbKMwdOZX234D27+/HTanDxl/0ZzLDARgcwvlNURfMtFqUxd2EZIwT MEOiFzB95ABzCi+KB36ixslizgEtbRJ3KSUJbfZ+Bu4lBEzRinqC99/ceHCEhosBOEJ/vIgq4tw U5NlXXvv7GEgalP7MsnGIQ1GcAWBR2Jdp7gMFcjwU5stNoVPf/w2dEOso2l7A26mTNNRpFdZq1b IfKvDvnYI/Tx2AlGz4AsQr03pn3KvPjL143VnxOa2vGqISQvYOsq46gGgm+RmaXLdr6owEK8BTD nmTDVY/qAtOeAjBMjM+Gm2IHKPKJu9Amrw8jikZp4s3OELO3dFAXRZmCNCTej2dLmPYJ/JoxeWY AAwCYafTydujQoYV1BKiv2F0XddhS14m0E7JM6+GAiUYAaFv1QrQpwFyfGQUJlSm/Coeux7oQOQ 1f9GWr X-Received: by 2002:a05:6000:25c4:b0:439:b62d:bea6 with SMTP id ffacd0b85a97d-439da36a70fmr19821869f8f.47.1773068994797; Mon, 09 Mar 2026 08:09:54 -0700 (PDT) X-Received: by 2002:a05:6000:25c4:b0:439:b62d:bea6 with SMTP id ffacd0b85a97d-439da36a70fmr19821798f8f.47.1773068994161; Mon, 09 Mar 2026 08:09:54 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 20/25] block/export: Add multi-threading interface Date: Mon, 9 Mar 2026 16:08:51 +0100 Message-ID: <20260309150856.26800-21-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069155094154100 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 --- 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 7c072409d8..1c79411839 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -259,6 +259,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 */ @@ -268,6 +270,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 Sat Apr 11 21:30:24 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=1773069100; cv=none; d=zohomail.com; s=zohoarc; b=cLM02y9/pbd4Zk3LBzQ3DivocDBlcoyDsGDexZcnCS/3Bhck5C1xcdtb5N3pD3AJgQYuyBguQNHVHTEfMoytU8gVMZm8sQapPKlF0loal3W/fYViEJmXZrQwJtVGjsBuBu5po7ihRyVM6U7eM40r8QVVroTcD7lYWcKlwfpDltk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069100; 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=GqVS3/ye8Htc5l6wtpJGivOQundgm2nE2RplGDI2HjOx2uECxgTcpCy8P38LpwJdgVk9+U00BppuaBNtAlaf7OzFlLTXX5dsVMyIx5A1kxMFsoWSw9wGYOJkHOKnRh6/7P3Dd1DpWaaH5cJ7XdIg1yIRRKvlR6hogwKBfh5Jc3o= 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 1773069100713553.3219331117632; Mon, 9 Mar 2026 08:11:40 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcFb-0001u7-OL; Mon, 09 Mar 2026 11:10:31 -0400 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 1vzcF9-0001No-Ht for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:10:03 -0400 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 1vzcF7-0008Ta-Ck for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:10:02 -0400 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-556-HMQN7ZShN7m17X3eKEUwSA-1; Mon, 09 Mar 2026 11:09:59 -0400 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-4837bfcfe0dso138898795e9.1 for ; Mon, 09 Mar 2026 08:09:59 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4852f6994a1sm159561035e9.9.2026.03.09.08.09.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773069000; 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=AXrq72qB/A0CPEKzJliOvxDsOd292vMDEEcWSThsJeSu4sdUydmihNcOW81bqxz6ZcMj7Y aSvgretfSuvopssTmMTjzVxwb2T6WTF7FBCLz+E2VGb+UiwpZ8pWdnZXqyOFXfEpm4VxM0 JLaoFyHuXTf0eE+ZNnbFazofnG4e1Lg= X-MC-Unique: HMQN7ZShN7m17X3eKEUwSA-1 X-Mimecast-MFC-AGG-ID: HMQN7ZShN7m17X3eKEUwSA_1773068998 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773068998; x=1773673798; 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=N8exZiqEagUDzUyj1VxYlFnefWhKAXfx2sWf8HYGezyh876kYJN2D8ddgbt5w8N7F+ pP85PLGRSBGcsCQcUFUo3HH2AaSUVqJR+/81gka5MUGBsjFxSsVX9ZTHZEQNtYHbTHz+ qe5CNxPMdcGH42kh4oqabeUgrIEtnLvU0fzOQxyQv2toffqClU/sX8/JhFj8tX9sCugu X/Hv9zV06XtB9t3ya24pS/lr1yLhrNpl95QfKksjmxcGV+47+5NB4hdj4YA9ZuHoayeM 8TBsxLAMbR75PkQAUN4Jaa4nC5YYA7nxg0oZ2tfymNIBh6miptNKBrhhhL0ogRjfT1JI vYXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773068998; x=1773673798; 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=KRm8vwhXbE8HMrXCKY8Sn3u4BGN/7E3m26ByDuPcMSEBOPrWtT8pq7qeuwuQmhaI2z oVykNbofHvF+9lhJlJdZJMQvZtiNXVhhFm6c2N5wRl9uuMj0rvK0kW7dDvq1oJbHzFV0 0E3mKVCRi2MGlOnV8/Yaro+GEmTXeBERIh1VIdlTgTWeSKYRp45XSrZky7uDRIp3h1kX DtNO0wN5/pnMQ/90i/by7ir4fK9QRqsljnIGARuUdZcC8hX9MJMxUgkSviy8bmeQm9Or uH9oab+6rquSZEktt1gw+2DoASOWqexgWP8kitxDQxwcbrzAkyEckzn5Ry92QbpZvYkg 65vQ== X-Gm-Message-State: AOJu0Yy5jBS6ggkgPazWfBOPi8uSRqKM3ccFN2f8jb8Qar9tuJ4w7kaw KRzZ1SPlyZLpBXDGPgrXZfj5kAWFLiTcNnXcnLaGYzjxSb6ENh/KhPnaqMwKOYpRfE0r+gN9jos yJOHu1hCru2T9CWxvvrX6d+uOE9F5lFCdw8P7IyI8y6OhCwxzlYUnXrUY0eXGFptm X-Gm-Gg: ATEYQzzfDeehMsgJFzw8ThaUxBAIdcDg10FJP0pZrqvjG3voVgdvvbnbLn4ZlaCxZt5 HIVPT2vhxWky1fscOSuVZG9URNyUdimT1m8FzZrY/9LJZDfYcpFbpB7KsOOnGiMe94Wz4SajyhO 6N+SY/9qiSPinmNDdi3mHF+VM8renRUAp2bC9vSXV02N+ez6J4+V0LKUCWyw2LxYPetUvFPyKLu keYzAhm9ZfiPudePgeiEPhNaJBETyZpGGy/cDR3zicgLNuMRAiVpqjHmKR+Bx0JQc6kD30mb62W LREDI41crBovIBxx9HKEU+wehn/8DS1CJ0BL+ALA1VSLkgM2Vtq4JmXWl2icxtL4n+amY1jLu2R ZlY9+qtxrBNwxnXQST/0III9OuLMmMdvNl65Gkhmr6DkXWPbmmFAG1w7ariKPUdCszil3Y4Wrz/ l4yUZO X-Received: by 2002:a05:600c:a0d:b0:485:1878:7b8c with SMTP id 5b1f17b1804b1-4852695b6fcmr184342135e9.18.1773068998028; Mon, 09 Mar 2026 08:09:58 -0700 (PDT) X-Received: by 2002:a05:600c:a0d:b0:485:1878:7b8c with SMTP id 5b1f17b1804b1-4852695b6fcmr184341545e9.18.1773068997581; Mon, 09 Mar 2026 08:09:57 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 21/25] iotests/307: Test multi-thread export interface Date: Mon, 9 Mar 2026 16:08:52 +0100 Message-ID: <20260309150856.26800-22-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069103069158500 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 --- 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 Sat Apr 11 21:30:24 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=1773069071; cv=none; d=zohomail.com; s=zohoarc; b=jZvvWk9bsCfVCdX/aaOu+kWS1FpEPUPCS05jkVD1xanxf7qTV8ZRgmerOjnRLhgfBSZwRS5F70YG7aeMhwxk1erAiP3lneWWIlbArOpLRQatlZq2gZV2w8umeQHMeiKtAz2pujmW+0slVaBorVG364+NoWM1J4M4ymsnr5iWx98= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069071; 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=633uGYxCqCqS9HhKtlvq4s6urigO3aDNgdTdJUn3P34=; b=nH3Fyo6O8mbWRZfH0vQWkbvrLmyh2px9TLqaykgCWcuiqnJAlyUROmExdu5rrSOARmRCK6bzae7lEjH5jrt48SnTa61aAxtZX9p0qoHR6lPVdIy1a9vw1oK4QfO8GRpH5ZvpiVYk/p687kNor2yNJ++KSkUrfkcY9yudHId2ByM= 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 1773069071527491.60237376326063; Mon, 9 Mar 2026 08:11:11 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcFM-0001Rr-DO; Mon, 09 Mar 2026 11:10:22 -0400 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 1vzcFB-0001PS-DU for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:10:05 -0400 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 1vzcF9-000071-On for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:10:05 -0400 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-62-8Gx2_sfkPUiwY1z01t2gTw-1; Mon, 09 Mar 2026 11:10:01 -0400 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-439b8bc43aeso6178011f8f.1 for ; Mon, 09 Mar 2026 08:10:01 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-439dad8d968sm26247465f8f.6.2026.03.09.08.09.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:09:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773069003; 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=633uGYxCqCqS9HhKtlvq4s6urigO3aDNgdTdJUn3P34=; b=PqE8Arsvk8AuUT2S0dQcrebo56mN9TA/G3noeVg2mNNWlrehpvscpQc36aDItu1JtRi6eJ 1oum5UTb+nZoBLDsURmUqgikXPqPBaj0kM1oy6aNx19SE1OxIbqlLFgsKC8ZfD42O50cef RDRdj+CnRSiJT17mTaf2tdqafgR9j9Y= X-MC-Unique: 8Gx2_sfkPUiwY1z01t2gTw-1 X-Mimecast-MFC-AGG-ID: 8Gx2_sfkPUiwY1z01t2gTw_1773069000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773069000; x=1773673800; 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=633uGYxCqCqS9HhKtlvq4s6urigO3aDNgdTdJUn3P34=; b=m6+3NHEHwA1ipH/A2JBXPM080Dx9SZnHHgD1vfsaQZini2Cr3Rk9Llt1uTLgOGRWBX +BKGdA8ANtNyOGJ+rSXduOEf1UV2MQXYVw9uJKoov0aqxmMZLBt9gfQ8f8b2DEvgfQoG 9bu5L7IotdIKtVTduSdZVdAnP+1Fqz7v2UMcEzSUvpbF88B2n90UtjwDPuHzTvv4ZpZS 9hD6sOu8r32Mn6E8yYLuWGiE6uFY9kfSinVWgFtCe1cQuXvkYP6EH0FiZB2zjcVnWPa9 8ThhnuifOffnv0IP4B5zinKro3H1f7GuuhFYjwh2QLXABSVOhjlc9r6yKKhKGdbWsm9L A7ew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773069000; x=1773673800; 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=633uGYxCqCqS9HhKtlvq4s6urigO3aDNgdTdJUn3P34=; b=ngerMhb/86U85Y30pB8MpaM4t5brzWW+z17eNO6uK9YfW8HZtQjjxvlygPXZP8s6Fb CQm1+IiElCap5qF2UHKVCgBVe2IUGs7vwNQ0jc6nzrQF5oPEeyAoDAb06ub/OTOP+Usq jRe33otZLMCvXQe7bFA952srsIYhYD7/gwwz28M0p+d3di30PE0v7k+l+MgLsV/tfnPk 7YlUAu3rHL9BJzyTwTOWNAV/MJQ1Mqqq9KNcdEVsavfjw4MqTDz3unp+2WfelPRcbOV2 1ZuLquGjVdxae/FlHnmZFJkO9YagmZEbfZgqkMnjI5hGTetx98rDAdWU4yoaPUXP7xYM N1uw== X-Gm-Message-State: AOJu0YypYE7O/GTuURlOaFL4xCRpj84RbwX1N1KPG8vUJLvIaXP5yRg+ 5FVWYuykGfOw6KVEuRmVw6kUuJEmIRW53WsOxrHeBHP6QcgAXFOgTLCPzcM3BsZMgvUPY0ta03j FiGwIaOMwpAqcJdt0maXzZTUBLIxyCRK9ijXOrbJ1XAn8StZNykB3dvyD X-Gm-Gg: ATEYQzx/rk08IizyPB7UktTEskU3JX3nUPP3fcZT8svf1GLUHGws7a9dNzCnSTlx7n0 bJ/FaQ4w+7BMCtl5c2uK8+r2+wgDAZx9t/hcwxCWl2pp6kzgDB3C4MC+PbllDUPjbd6kmtrYn+b NkDoC7937Gn3MeWJqoNgQkvjs7jv2HA7HQ321xK3SqZIFXE3SPYcePmieUN397M+/3+owsmp5hV 0FCk4kaGzln9B5KkovjghUT8uoZnjjub34GpA8A4GUW1KM5c512cPkJBMdX6kuTmn0979fGunvw TojoSLaUKSzDduFt4xU+tJECS62AOwJA195ei+J3S78QlsMGnMOnw3KbBZNbz4gw0wCYY9nQR87 x4i8Zs921APmcfPgBFhO4ejjrLqQorm+sHUWyinqIwmFJFim9Cj2KKXcjY9OWKJnbymfqSbEir8 +cKAIc X-Received: by 2002:adf:ff89:0:b0:439:de1d:74c6 with SMTP id ffacd0b85a97d-439de1d76famr14581666f8f.19.1773069000323; Mon, 09 Mar 2026 08:10:00 -0700 (PDT) X-Received: by 2002:adf:ff89:0:b0:439:de1d:74c6 with SMTP id ffacd0b85a97d-439de1d76famr14581620f8f.19.1773068999863; Mon, 09 Mar 2026 08:09:59 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 22/25] fuse: Make shared export state atomic Date: Mon, 9 Mar 2026 16:08:53 +0100 Message-ID: <20260309150856.26800-23-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069073907154100 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 --- 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 1c79411839..fe1b6ad5ff 100644 --- a/block/export/fuse.c +++ b/block/export/fuse.c @@ -156,6 +156,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; @@ -266,6 +267,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); @@ -334,12 +336,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 */ @@ -817,10 +820,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, @@ -903,15 +906,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 Sat Apr 11 21:30:24 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=1773069083; cv=none; d=zohomail.com; s=zohoarc; b=LO1LOd7XLpyLDPJfNzKZGEks1MJfr3eE6bonPrwrhj5ilmmZjORhlmoW/HTFZ2Z5vrjHOqWWYcAyauZmRoknEU4HjN4IbiFqjKQa5AsiI8BF5DK7aKLpPRMM8RTFIYLgajONl8sOGaFyWcjSdtBVev9bgRaHcDQGaIHrQZ+zFeo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069083; 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=W9Rz352gPbVCXsnI9PGbxy5vJFui4fw6p0MlUSQyxPo=; b=aIFLF5BJHM64dECvnQB2cyyMKOemEHVNeq0wh8eqB1rxWiP/2Dql5i6FW+d1/RFWZeGwTL5Hzqgl/ezIBXkqDmBx35waTCKebZGy/3mLqYVSdpBSccm4sN6/kFsrEXk30nuk6HTwrfF8qemijOo/M9QacyD7Lfo9k4cHW37FJVQ= 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 1773069083798286.8459270262978; Mon, 9 Mar 2026 08:11:23 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcFu-0002GJ-Cz; Mon, 09 Mar 2026 11:10:58 -0400 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 1vzcFH-0001SQ-8U for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:10:15 -0400 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 1vzcFD-0000HF-At for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:10:09 -0400 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-568-MZX6QSbxNBapBsgo8BlHaQ-1; Mon, 09 Mar 2026 11:10:04 -0400 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-439b9116e2eso5379943f8f.2 for ; Mon, 09 Mar 2026 08:10:04 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-439dad8daf2sm27880789f8f.2.2026.03.09.08.10.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:10:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773069006; 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=W9Rz352gPbVCXsnI9PGbxy5vJFui4fw6p0MlUSQyxPo=; b=DsHSQrLi6ADLuOBXCuuuXEDZQ64CAJ9vuv+hq/muPKy8iM6pEA4ow2XXnRXzCHBHCRimtk egokuvSMn+hVCsgVez7qiSDkDEZPmX9/lIxKlxjmRbJcm6zVL4WxNW3WKAqlTynyfznNY8 KK3FKnjqK59Gw59KVtFsvuAi/W75zyA= X-MC-Unique: MZX6QSbxNBapBsgo8BlHaQ-1 X-Mimecast-MFC-AGG-ID: MZX6QSbxNBapBsgo8BlHaQ_1773069003 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773069003; x=1773673803; 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=W9Rz352gPbVCXsnI9PGbxy5vJFui4fw6p0MlUSQyxPo=; b=YLhhtJr2eECd4QA6N1yS4eUYKkgs8weVQU7h5EM916ch4htqTw/TwIKFMLtpmFvgro HWfsDUtC915fwrEAKJ7/JhVBkkbX9YnCg8syCbUnQA6bfSMp4CTXrm5rsBUqEFquXLeT fdx6asPkyAsZEMYiWS3SqXPdzxC+NnoscAsgJsyFLP2VhkpI+hI0aHnallABb6eNNFgy eo+hGh9/TcMT4KIRRF6S3eeXrIJ+m+VOEN03ncBsQUsbySiWOyA6dqpYyp3NrZ3jFb7G v5JkZTefRQmwCwl9swq5une5mloMZnUFWKH9Tm/lBhoONkMhbelvTr1TYfgjiPxLwMp8 8Zzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773069003; x=1773673803; 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=W9Rz352gPbVCXsnI9PGbxy5vJFui4fw6p0MlUSQyxPo=; b=Q7sUzp8Nnn4Xmz5JpXQjk03I2AWhVa7sRq4I3g/zP2SnOUImhfp1B6Rb7XaVF6tQqz x+30+gv0OoZ2mK4B2Rkx2sHPxPO0kMpsmNvq3Dt4VOGnAjIwzp0tMQCzGX4kQyIPELWV /pkvx64Na03bbqMADLwabeXG1tBgVF6nm+6NV8YMqZBAT/87ldAlCux36DxKZ+JLKiuN 61jC+QKksg8oGouaoBWwzcTGjD/r4YoFfSSlXXBIh25HR5qlDtCXZ7SNDTcdgK6qHY9k nv054d9f+tbduu2Jjb12a1zom/pohlbs8c5roXJJHZLU79KHzmgJbsTmXL9pNrhaS+wJ jXIA== X-Gm-Message-State: AOJu0YzZoZIc+8eMsg7cBx/uYh0wVFvjchWbnNyYQGnYNZvwP3/nwXFY p1WpBKgEXGSY5LCT5eHD+b0JzomEQxnuU0YH2cEJCdQpYsR4Jpt2082AJtsXmYbt1PGA9R+LPKI YANC3+fseG+B4w/LfhtxM/Vw8rLgMv2qLOmOIJERcjv23g3rLZUvWS9Br X-Gm-Gg: ATEYQzwzBVcdh4fIgGoKr4bVDJWs/G0eqthL/5eojJ2MW/0qnQmO1yUfr65h6ztYKd/ ULoXuvLiWb/ksOWZgiXJ8Xhbr43o2zeHQ+M06ZxVz01w4wt3ex+ZqZLPjDNMP3JE49duQPRgeTw 5rscQEAeR4N8Nzzh3NV/k6JagBWUG1vE4gdfTI0VF/zCAhS9vuroodReACGhE54NXIB2yvFQyKQ IwTvQSL2ZCMC1yTb9u5tgLg88hEvLF3NWY44sVZ6JezW20mhBqHYU8l+z2KzzacWMwr5MdRlv9O ody7id+5iRIvcS626Gyu/XxyMcbSn0VO1F7bzCmQSmtd93456uMILoTi/qRg171M8XsRXRsY3bW XJKHowB5TWAtOPml4dXFTXrmAEohi5bOViBf0WAJ53aVW34YHsfIrxRrtkY0G5jOFPRqSrUnGB2 2/KUkX X-Received: by 2002:a05:6000:24c1:b0:439:c43a:accd with SMTP id ffacd0b85a97d-439da6693f5mr17423815f8f.27.1773069002966; Mon, 09 Mar 2026 08:10:02 -0700 (PDT) X-Received: by 2002:a05:6000:24c1:b0:439:c43a:accd with SMTP id ffacd0b85a97d-439da6693f5mr17423751f8f.27.1773069002411; Mon, 09 Mar 2026 08:10:02 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 23/25] fuse: Implement multi-threading Date: Mon, 9 Mar 2026 16:08:54 +0100 Message-ID: <20260309150856.26800-24-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069086067154100 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 --- 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 fe1b6ad5ff..a2a478d293 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 @@ -118,12 +120,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: @@ -140,6 +147,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 @@ -148,7 +163,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; @@ -160,7 +183,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 @@ -179,12 +202,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 @@ -216,8 +240,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 @@ -226,8 +253,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 @@ -242,6 +271,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 @@ -273,8 +307,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 */ @@ -286,7 +344,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 @@ -362,13 +420,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 @@ -461,28 +529,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); } @@ -528,9 +596,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. * @@ -538,8 +639,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; @@ -551,7 +653,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) = }; @@ -612,29 +714,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 @@ -659,6 +761,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); @@ -667,7 +780,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 @@ -1344,10 +1456,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; @@ -1471,10 +1584,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 Sat Apr 11 21:30:24 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=1773069096; cv=none; d=zohomail.com; s=zohoarc; b=RksscnzcgFQJ9dSl+C4TpZySXhclGQ+6FuNy35wQLSoa2q8BEz2IIZSoP5JTe8+fL00xlSDpF7FS1HAVlyjEKNHcrHdtD/+sV8D32iwRxfnGjKlxrQDDcH9IoarldQXEIdl6d5dHWNJrWkNL03b6X2LTyjOC788wsZcvjnllKSE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069096; 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=YEWGchxh+W3/ZtytWCiqRbpwKupDG+yMYsuOkJi/XSa4/RSVGQoGh4uiI3bpxDgOw3aoakI6Dk9HsbFY9jgS0DkV90qfPoj464uhB/iFqOy2fXnTWT4mtWHyDhJUUXEnl1gu7e50nKeZtczPjDk4cxq6s1LQsEAKHFNOvRrcTN4= 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 1773069096894795.294012677535; Mon, 9 Mar 2026 08:11:36 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcGP-0003Ue-H2; Mon, 09 Mar 2026 11:11:21 -0400 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 1vzcFP-0001gw-9l for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:10:30 -0400 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 1vzcFG-0000Hz-SR for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:10:13 -0400 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-530-fnYNy0oAPU66XbE3NDkCKA-1; Mon, 09 Mar 2026 11:10:06 -0400 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-4853ac455b2so12474815e9.1 for ; Mon, 09 Mar 2026 08:10:06 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-485245dbe50sm91408945e9.17.2026.03.09.08.10.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:10:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773069007; 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=D8YG34+jjwta7P4Ndo8Z3aO2mD3LzqxWnRJNqiUrt5/D0jYOLKGSX+oIk1x0m92qIG3ncN b65xWF8V/S1QurYRRn4JspaTnAppxw0rBl5KBPJPKH5p9GW3TXP64dV/zYfbw9GaAfLnx9 hc3gdiAIpP3iC9VTGM++n5nFsy1DwCQ= X-MC-Unique: fnYNy0oAPU66XbE3NDkCKA-1 X-Mimecast-MFC-AGG-ID: fnYNy0oAPU66XbE3NDkCKA_1773069005 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773069005; x=1773673805; 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=dXRWrzARBBNyg/qVYYducm74ox3QsCIempB3Hr18Hgl5UjE/KMOFCcLa43tPm/FPFx sSA65VHOfGi/fhn7OEaurERLNoHQ765CayNqeKLNAPNLGkJMDBLgjh2sUYXhrqj1Dqov nTsLDG3a38bcGnC0jOmBx2EegL5B56lw+KAaRx2/kNaq0OpjgD+WXmITYTyq+FUNuAYx c0dOu8/fFI2m8fclA1Cn5Cm2RlPU1utivYfs/JFsNLAVqIAJ8et2CVl84nGZdzZSNKGL h8B0vP9ohz+uoZdCvg494A/DH3StsDs5V7CPXmp8isUB/A6ZL6mm4kBZFAP6UMKHCwbB rvig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773069005; x=1773673805; 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=VDGWkXceKnYrYyxemzPjefvNkYX0Z3dcdvlPr/yqrdU9lO/7/yUTxClkZ1PbaSQsQs sGYeAKmh5AeMmlOxEIhEvR+WwoXIY8roIqk0kBC6D9B3ZHXAO0H+Jjy1IKvwbC+TOLC4 UJH4GTTsATBcWZw+ZBDYfob9rr/cX56ES3ufDcEgWBtD3PPJnwpaZ9Y5innHkNpLOoRw /F76EE+Hg3KP3hMBWxYhl6wPZw+JVJcP8ZwC5MrLhhf+niiTgEKhZx4Hj9XL7A7fmNPY rcd4p/VQ9xs93PLXzg3532vF5a07/wBe1CEAt1ScezioDb5RxYHUYKP3Z1qmZUFaPpi9 JfSg== X-Gm-Message-State: AOJu0Yya59Bxbd5DInKi7hEsV7zAwKPJXmgs7HqilcaaGH9diBGFL6kK mEPjbPuvBPB0snbbJsSU/25jNVLLjME6zYWOlGFJWGStbBM1+eEFlG/vCQzZU1xK8gZTeFaGi00 w+s1fFO3Ey+RGg11EzZMBSENd43drTBYOUFq75nGfgEfanabHtkT2yWjC X-Gm-Gg: ATEYQzyEP07ZTZ6Jld3ARQHQeXJzkXFDdsAsGGrQINoTJ6hXT8xtBQG+3MRtfzNLcOO TONPO3irBOQZWBZIzftf4Y5/av3Xcac6hEQ7XyT0odiY8vKZD8xXLl3DtcHYdX1OpguM21WrxAP MvUYg9SM2z8w1QZqt6Q5mQRiuFyS9pdvM7bN0vODgsTrUG+MdkU8UHMilIcV98kxePT2VCP+4ef bEV/Wh5dNdMSGtCDP0YOUwrXIDl8c2jmLCkIfrfK+E3e8RUMq3j1PmRH6CDXAtxgr9CvVI/2EjA +I4/DV+sZra9S5JuYLFjm9C/AClbqPk9qowgZa5qKZlZh58iieIThlk94lrvdu8eB2QdaUsShSw z1fhMmqucVjqOkFGFIvzGshJAEYq1Rex5buY7WbFU0oIzSjRBBKt6eW/orka2ZjMOxFEiPOs2O3 BvJu/3 X-Received: by 2002:a05:600c:4445:b0:483:6a8d:b2f9 with SMTP id 5b1f17b1804b1-4852690febamr208987695e9.5.1773069004998; Mon, 09 Mar 2026 08:10:04 -0700 (PDT) X-Received: by 2002:a05:600c:4445:b0:483:6a8d:b2f9 with SMTP id 5b1f17b1804b1-4852690febamr208986955e9.5.1773069004559; Mon, 09 Mar 2026 08:10:04 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 24/25] qapi/block-export: Document FUSE's multi-threading Date: Mon, 9 Mar 2026 16:08:55 +0100 Message-ID: <20260309150856.26800-25-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069098164154100 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 --- 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 Sat Apr 11 21:30:24 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=1773069099; cv=none; d=zohomail.com; s=zohoarc; b=ctdBL/kKUhuVb9erqnpVZhzjCe+r9zMsFHFeOrYHy02jnh8vqgb3h44I2lP0yO+l6MN+2ftWFstpS8Av8GCc1qy1jNc1c7zOmS+AX8s9CsV+VQgsh/3ebAJkCe4vRSVjXY+m5cahCeN2qtoL94EBHMvreGDQ704+wz9Kn9o85zU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1773069099; 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=B3tf5m+TNYnDNSRa6uE6yRssUtqOWimK8Q3H8Fct3/SMynzeYijTOyFCHPSWQRJooygzq4F2iXDhW95EMqIRVMrv+7kjO+acZnXLDp3OCdC+Qocne+ovh7ueXZ1TN0j8Gq8mQx1NcH+iLE894nxlx3WU5vZIcfZG2OzuLCKxPK8= 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 1773069098855650.9779804883469; Mon, 9 Mar 2026 08:11:38 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vzcFq-0002G4-42; Mon, 09 Mar 2026 11:10:53 -0400 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 1vzcFP-0001h1-CH for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:10:30 -0400 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 1vzcFH-0000KW-1l for qemu-devel@nongnu.org; Mon, 09 Mar 2026 11:10:16 -0400 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-651-9s71jmydOhOo-wSGFQ_d-A-1; Mon, 09 Mar 2026 11:10:09 -0400 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-48378df3469so81845605e9.1 for ; Mon, 09 Mar 2026 08:10:08 -0700 (PDT) Received: from localhost (p200300cfd737d0cf29d515fbd6051d53.dip0.t-ipconnect.de. [2003:cf:d737:d0cf:29d5:15fb:d605:1d53]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4853588758fsm75122675e9.4.2026.03.09.08.10.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Mar 2026 08:10:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1773069010; 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=Y93YJ+oGt7FvqQ8uoS8S8Te2lYowEqBIDDjxBRmDMuVpdBk/fQamcO1Vvg8p6xrFi4qeQc x/+K3iw4AGePiB94IUzMluAZ0n/sYpVMdRu0tsewwz6rdMYnTIDKAPN/PoIiIgQHiUSyqx porVhPMZZj9sCEXgGU3rKe+E1GFbpVU= X-MC-Unique: 9s71jmydOhOo-wSGFQ_d-A-1 X-Mimecast-MFC-AGG-ID: 9s71jmydOhOo-wSGFQ_d-A_1773069008 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1773069007; x=1773673807; 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=NMnwyVDbF6bjaYnjBgk4muAa144na2u/fIHBmkd47W95pWmgwP4Bm9s3Do/EeuMbSG 4LRKMidCUOQAY7DmegR7OzPc8RPcfOEXYw5YjI+t90YdT39u5mm8mH1L1UcCOSTH/W10 Mbg+4IV8aj9NO35Q/qWfpl3bpaxsolDM3D5dqTRc+0wIRpgqTBkwqaSwhkSFDuqs7MNh tjmS/8Tf6pwuAvLHlaNuk50cnvmpzwSxWjHI2DxhW10k2AUck5L7lDPMvTGmXjFTOT/w 7xtVHsP7xvan8K2JhuOTGP4HTHyoiEG+1xypMr/E1WhpavIuShXNytPvxDMBPp2ocoiP A1IA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1773069007; x=1773673807; 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=jfX3k/BDaouGZHDDCKszr0RGPtwj4VwX9P0WFWsbeYXDHirmf1ZG2l/x2GLAJdJfmS 3AEtyDSi5rQP6o3iVnUT+evd81c6d8iNophJF2GhOHdM6kedV4//cvDnsI/BpplOfMS/ 0QsM3LqKd1F6JwaceITB/wkflRRr4PM+3qNbazbofsHkEotIBsV8fju0/VKXsDxQJoCv Eigz0m5w4Vi0lPljAlPaLasM3V+ifb1ggBNPWi4LFUPzEJ5D2fjtNm1HhUIkcTrEvhcR OxsiBScYtS8aH1wmBIDqcu1hj28/jERFfpYUBASqZkpvaLdsZdbc/B4bMoHZJMopfsgb 7AgA== X-Gm-Message-State: AOJu0Yy76+8cVvGxoSwzPRTL6y2iyLASWaik8lobf8PGzPyzO5tYlvxk KDbdI/wL8b2BP1X0+XQXfAb9kqwWdKZr+1s/1eS55xvpcmyEsBOgbLgAy62PrqvPt1CR/eNmvE8 Z+6OI1oSYoC0U5WknosgRlpUedqd/Dcn/7aR4ph9WTecmy9fWb1h0iiqfEdsUJP0K X-Gm-Gg: ATEYQzz0mwiLNtO4CEWzBU+RbcDwuNLZcgorSKZ5vCQgh+BkIl00XskNh9aIs3Llla1 n9JQkXlyH/01hpqvuzZx7F6hSZE28umn+vgGqqllPhDL/GvQW/b/FoVqUQ2Eva/W97rZJ0SBXzQ bZ9zGQXhic81gfoYIzyJLCjgszKl9j1uBySx1vGxldTlcJxQVxOqpOsWwAjnyjLxjiDaHXnwcFT ycirCBu3SwEzRUxDDlFzMR53u+hHrWADzcupCrx2NNsJadTde7FX+AthoOVU4mdJxD6Px/LeIM8 sbaukssH+05wCcMmCGzOLoWKxdoVDtvzInJYOV7Yy7AmWAdpilC3Vo0GJZOKYgNYyliX8AtL/Hq V8lVz7m0u9JqY0+G3WsxdeRsUUTBqzJ5/dAYrw09psjYYdVX45wJHixRgCDUtHJZfutwro3zdgt eFawDa X-Received: by 2002:a05:600c:64c7:b0:47e:e59c:67c5 with SMTP id 5b1f17b1804b1-4852671d9c3mr179495695e9.8.1773069007468; Mon, 09 Mar 2026 08:10:07 -0700 (PDT) X-Received: by 2002:a05:600c:64c7:b0:47e:e59c:67c5 with SMTP id 5b1f17b1804b1-4852671d9c3mr179495145e9.8.1773069006952; Mon, 09 Mar 2026 08:10:06 -0700 (PDT) From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Kevin Wolf , Brian Song Subject: [PATCH v5 25/25] iotests/308: Add multi-threading sanity test Date: Mon, 9 Mar 2026 16:08:56 +0100 Message-ID: <20260309150856.26800-26-hreitz@redhat.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260309150856.26800-1-hreitz@redhat.com> References: <20260309150856.26800-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: -3 X-Spam_score: -0.4 X-Spam_bar: / X-Spam_report: (-0.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, 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.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no 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: 1773069106337154100 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 --- 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