Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2197747/?format=api
{ "id": 2197747, "url": "http://patchwork.ozlabs.org/api/patches/2197747/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260218132633.29748-2-hreitz@redhat.com/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260218132633.29748-2-hreitz@redhat.com>", "list_archive_url": null, "date": "2026-02-18T13:26:10", "name": "[v4,01/24] fuse: Copy write buffer content before polling", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "d31153fde76e4e7402f85dd15aaf4292e869d78c", "submitter": { "id": 82279, "url": "http://patchwork.ozlabs.org/api/people/82279/?format=api", "name": "Hanna Czenczek", "email": "hreitz@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260218132633.29748-2-hreitz@redhat.com/mbox/", "series": [ { "id": 492547, "url": "http://patchwork.ozlabs.org/api/series/492547/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=492547", "date": "2026-02-18T13:26:09", "name": "export/fuse: Use coroutines and multi-threading", "version": 4, "mbox": "http://patchwork.ozlabs.org/series/492547/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2197747/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2197747/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=mimecast20190719 header.b=iL6DYDVb;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256\n header.s=google header.b=m3dskqsJ;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fGHYv1bgVz1xvq\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 19 Feb 2026 00:34:59 +1100 (AEDT)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1vshfb-000486-Dx; Wed, 18 Feb 2026 08:32:47 -0500", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <hreitz@redhat.com>) id 1vshfT-0003yj-OM\n for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:40 -0500", "from us-smtp-delivery-124.mimecast.com ([170.10.133.124])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <hreitz@redhat.com>) id 1vshfA-00052x-N6\n for qemu-devel@nongnu.org; Wed, 18 Feb 2026 08:32:37 -0500", "from mail-wr1-f69.google.com (mail-wr1-f69.google.com\n [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS\n (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n us-mta-64-KFCd-gTGPL6FS4Anet0x1w-1; Wed, 18 Feb 2026 08:26:46 -0500", "by mail-wr1-f69.google.com with SMTP id\n ffacd0b85a97d-436267b01c4so4787945f8f.0\n for <qemu-devel@nongnu.org>; Wed, 18 Feb 2026 05:26:46 -0800 (PST)", "from localhost\n (p200300cfd737d029edef7b8da7441ac2.dip0.t-ipconnect.de.\n [2003:cf:d737:d029:edef:7b8d:a744:1ac2])\n by smtp.gmail.com with ESMTPSA id\n 5b1f17b1804b1-4837e565f5esm419468275e9.10.2026.02.18.05.26.42\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Wed, 18 Feb 2026 05:26:42 -0800 (PST)" ], "DKIM-Signature": [ "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n s=mimecast20190719; t=1771421520;\n h=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n to:to:cc:cc:mime-version:mime-version:content-type:content-type:\n content-transfer-encoding:content-transfer-encoding:\n in-reply-to:in-reply-to:references:references;\n bh=KIrJYrtnoXwxSw4V3NuTZZEpmlWDoM3vKo2sYuFFuvk=;\n b=iL6DYDVbeTt8yOV6GAWNwI2Jr5jJB+K0cVAn0xhJHC1Q5eLK7D8wjolMxRpOKj6AEqe7jR\n pl4dg7iat/25sd58maEiNwYz+CF6M8HfL5p6fwpR8PMaTOLalzgLc5zvsT6aAXVbXU+XFZ\n q4Ked2TghRNVifSPX18qpURYLIdICIA=", "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=redhat.com; s=google; t=1771421205; x=1772026005; darn=nongnu.org;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=KIrJYrtnoXwxSw4V3NuTZZEpmlWDoM3vKo2sYuFFuvk=;\n b=m3dskqsJNpNW1ywXhelYIoKfU9yUd4gdfbfXpFkS+mK/ePYMopLcRdGEtdXNJxjGsu\n /kv3p5F6SnWsydsFy3kiY4YT10gnJrv8YBTLmvimcAiCpv2yJmWkKEHsnavfENlJhrNm\n Y9g8kWvSY4hbAiWzUEaSlBzSRKEChzt+VlakiClYytJwmahfle4BrPDbhrB/fW5tFJ2j\n ainQyVTBggsMup/HRl8z/hETTaq4/TScRfbjxMGcNijM5WJ8TOwBz6vy0vVaTaXV14uM\n ApF68Qn7LBp30nmDF9H7N0IeQAs1d8KVnm0GXPhE+A2AFqTYHEhNz3CdE4rNgmh70bhi\n hIIg==" ], "X-MC-Unique": "KFCd-gTGPL6FS4Anet0x1w-1", "X-Mimecast-MFC-AGG-ID": "KFCd-gTGPL6FS4Anet0x1w_1771421205", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1771421205; x=1772026005;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=KIrJYrtnoXwxSw4V3NuTZZEpmlWDoM3vKo2sYuFFuvk=;\n b=oNOgGzDXPHELCRqDlr9CCWyUoHpNb+532dLB5Ks31OiqGH5Jr+13Qwf3J25L+ePK7q\n zAEqpu4cTM2N7VNPfbTOSwoVaXoPu3FZt45hSVhjH9X815LZ5yu6GALVRGgOeLqbFjI7\n O5tHlwR6f+1nuKFoKF1EFL1QLv7RF8+S6qhISj0V9U0HaTAbQlmVmgACDuN5UF0sEY1V\n RDOgJSQkZZMn9WaDHsQuM1zi3UAJV0n+z73HRTPb1zjeDDFL/yksm303EC0kTpZ7w3nB\n aCJ7J+tCAiWeKl8u6kU5jQzz5ff9/APE4ydGFhfzR0N0Ydz/RC6e1cezG6aPOACnYNAV\n KgLA==", "X-Gm-Message-State": "AOJu0YwNSwknT/Tca5BrPSywYWvSe8J5cMudBUDPG4MhRbQzXBp90p6B\n +VSwIQCT4SEewNbOj2yqIdd9Dkr6W0bx8rAMAsHya3Adud8zdRqdpAAwfYoEqc3MJmhZIphpTw8\n OgWMUlt5+u2MnrC6/6iM7dku39MmdEfWrqJHc5myKPO5fIRGEn3lcn1X+", "X-Gm-Gg": "AZuq6aKKOFglxmgd+HvlZ2gJOTNXgnhepeRSiakKn/pncGk6NPCZhzLd+DYAw/KRXMV\n VZ8Yn0RJxXbr5SGoo5s3drC5PAd38zxr/FeekJsyUPRl4J8sffyqxLzjh0H0zDzQEjKgLB4DLg9\n 3VNY89063AlIwQ66kMnTMWqf8yZauvpTEB6ez/MLpr0ECHWG7tpNBVY2MBy7WCY/v/SIBf+SIv3\n K8UGQZnFQ13niTqEhWq0PwQKLAd125vlsyKmAJ/CqgCPNEH/6/JJkfPfBHTnxop/GNHFrmg+tz3\n v5eeFJE9R68EZHi6UTCubE9kdvAvn3Ls/xLerEgxkGobi/tqMEgVFwXYqOvz4OqWGDgGsyLFccV\n sTIiVrbS9pCuKUgCYFxAfWDcJdHvhB02SZUYLLeOghjSKEUF0XCzfAgxPyeJg2Virc8GTuHMFD0\n ectmcu", "X-Received": [ "by 2002:a05:600c:8219:b0:483:6bb1:117 with SMTP id\n 5b1f17b1804b1-48398b7d878mr31983425e9.32.1771421204962;\n Wed, 18 Feb 2026 05:26:44 -0800 (PST)", "by 2002:a05:600c:8219:b0:483:6bb1:117 with SMTP id\n 5b1f17b1804b1-48398b7d878mr31982945e9.32.1771421204477;\n Wed, 18 Feb 2026 05:26:44 -0800 (PST)" ], "From": "Hanna Czenczek <hreitz@redhat.com>", "To": "qemu-block@nongnu.org", "Cc": "qemu-devel@nongnu.org, Hanna Czenczek <hreitz@redhat.com>,\n Kevin Wolf <kwolf@redhat.com>, Brian Song <hibriansong@gmail.com>", "Subject": "[PATCH v4 01/24] fuse: Copy write buffer content before polling", "Date": "Wed, 18 Feb 2026 14:26:10 +0100", "Message-ID": "<20260218132633.29748-2-hreitz@redhat.com>", "X-Mailer": "git-send-email 2.53.0", "In-Reply-To": "<20260218132633.29748-1-hreitz@redhat.com>", "References": "<20260218132633.29748-1-hreitz@redhat.com>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "Received-SPF": "pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com;\n helo=us-smtp-delivery-124.mimecast.com", "X-Spam_score_int": "-20", "X-Spam_score": "-2.1", "X-Spam_bar": "--", "X-Spam_report": "(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.043,\n DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001,\n RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001,\n SPF_HELO_PASS=-0.001,\n SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no", "X-Spam_action": "no action", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "qemu development <qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org" }, "content": "aio_poll() in I/O functions can lead to nested read_from_fuse_export()\ncalls, overwriting the request buffer's content. The only function\naffected by this is fuse_write(), which therefore must use a bounce\nbuffer or corruption may occur.\n\nNote that in addition we do not know whether libfuse-internal structures\ncan cope with this nesting, and even if we did, we probably cannot rely\non it in the future. This is the main reason why we want to remove\nlibfuse from the I/O path.\n\nI do not have a good reproducer for this other than:\n\n$ dd if=/dev/urandom of=image bs=1M count=4096\n$ dd if=/dev/zero of=copy bs=1M count=4096\n$ touch fuse-export\n$ qemu-storage-daemon \\\n --blockdev file,node-name=file,filename=copy \\\n --export \\\n fuse,id=exp,node-name=file,mountpoint=fuse-export,writable=true \\\n &\n\nOther shell:\n$ qemu-img convert -p -n -f raw -O raw -t none image fuse-export\n$ killall -SIGINT qemu-storage-daemon\n$ qemu-img compare image copy\nContent mismatch at offset 0!\n\n(The -t none in qemu-img convert is important.)\n\nI tried reproducing this with throttle and small aio_write requests from\nanother qemu-io instance, but for some reason all requests are perfectly\nserialized then.\n\nI think in theory we should get parallel writes only if we set\nfi->parallel_direct_writes in fuse_open(). In fact, I can confirm that\nif we do that, that throttle-based reproducer works (i.e. does get\nparallel (nested) write requests). I have no idea why we still get\nparallel requests with qemu-img convert anyway.\n\nAlso, a later patch in this series will set fi->parallel_direct_writes\nand note that it makes basically no difference when running fio on the\ncurrent libfuse-based version of our code. It does make a difference\nwithout libfuse. So something quite fishy is going on.\n\nI will try to investigate further what the root cause is, but I think\nfor now let's assume that calling blk_pwrite() can invalidate the buffer\ncontents through nested polling.\n\nCc: qemu-stable@nongnu.org\nReviewed-by: Kevin Wolf <kwolf@redhat.com>\nSigned-off-by: Hanna Czenczek <hreitz@redhat.com>\n---\n block/export/fuse.c | 17 ++++++++++++++++-\n 1 file changed, 16 insertions(+), 1 deletion(-)", "diff": "diff --git a/block/export/fuse.c b/block/export/fuse.c\nindex 8cf4572f78..cea9de61f1 100644\n--- a/block/export/fuse.c\n+++ b/block/export/fuse.c\n@@ -301,6 +301,12 @@ static void read_from_fuse_export(void *opaque)\n goto out;\n }\n \n+ /*\n+ * Note that aio_poll() in any request-processing function can lead to a\n+ * nested read_from_fuse_export() call, which will overwrite the contents of\n+ * exp->fuse_buf. Anything that takes a buffer needs to take care that the\n+ * content is copied before potentially polling via aio_poll().\n+ */\n fuse_session_process_buf(exp->fuse_session, &exp->fuse_buf);\n \n out:\n@@ -624,6 +630,7 @@ static void fuse_write(fuse_req_t req, fuse_ino_t inode, const char *buf,\n size_t size, off_t offset, struct fuse_file_info *fi)\n {\n FuseExport *exp = fuse_req_userdata(req);\n+ QEMU_AUTO_VFREE void *copied = NULL;\n int64_t length;\n int ret;\n \n@@ -638,6 +645,14 @@ static void fuse_write(fuse_req_t req, fuse_ino_t inode, const char *buf,\n return;\n }\n \n+ /*\n+ * Heed the note on read_from_fuse_export(): If we call aio_poll() (which\n+ * any blk_*() I/O function may do), read_from_fuse_export() may be nested,\n+ * overwriting the request buffer content. Therefore, we must copy it here.\n+ */\n+ copied = blk_blockalign(exp->common.blk, size);\n+ memcpy(copied, buf, size);\n+\n /**\n * Clients will expect short writes at EOF, so we have to limit\n * offset+size to the image length.\n@@ -660,7 +675,7 @@ static void fuse_write(fuse_req_t req, fuse_ino_t inode, const char *buf,\n }\n }\n \n- ret = blk_pwrite(exp->common.blk, offset, size, buf, 0);\n+ ret = blk_pwrite(exp->common.blk, offset, size, copied, 0);\n if (ret >= 0) {\n fuse_reply_write(req, size);\n } else {\n", "prefixes": [ "v4", "01/24" ] }