)]}'
{
  "commit": "a3fcbca0ef643a8aecf354bdeb08b1d81e5b33e7",
  "tree": "f0a48a0cc0b5947e18d67c9d9a5e907f23d6cfb4",
  "parents": [
    "31ee190665dd50054c39cef5ad740680aabda382"
  ],
  "author": {
    "name": "Hanna Czenczek",
    "email": "hreitz@redhat.com",
    "time": "Mon Mar 09 16:08:32 2026 +0100"
  },
  "committer": {
    "name": "Kevin Wolf",
    "email": "kwolf@redhat.com",
    "time": "Tue Mar 10 12:11:16 2026 +0100"
  },
  "message": "fuse: Copy write buffer content before polling\n\naio_poll() in I/O functions can lead to nested read_from_fuse_export()\ncalls, overwriting the request buffer\u0027s 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\u003d/dev/urandom of\u003dimage bs\u003d1M count\u003d4096\n$ dd if\u003d/dev/zero of\u003dcopy bs\u003d1M count\u003d4096\n$ touch fuse-export\n$ qemu-storage-daemon \\\n    --blockdev file,node-name\u003dfile,filename\u003dcopy \\\n    --export \\\n    fuse,id\u003dexp,node-name\u003dfile,mountpoint\u003dfuse-export,writable\u003dtrue \\\n    \u0026\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-\u003eparallel_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-\u003eparallel_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\u0027s assume that calling blk_pwrite() can invalidate the buffer\ncontents through nested polling.\n\nCc: qemu-stable@nongnu.org\nReviewed-by: Kevin Wolf \u003ckwolf@redhat.com\u003e\nSigned-off-by: Hanna Czenczek \u003chreitz@redhat.com\u003e\nMessage-ID: \u003c20260309150856.26800-2-hreitz@redhat.com\u003e\nReviewed-by: Kevin Wolf \u003ckwolf@redhat.com\u003e\nSigned-off-by: Kevin Wolf \u003ckwolf@redhat.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "8cf4572f78d5b2aac74410d21caa367ed331492f",
      "old_mode": 33188,
      "old_path": "block/export/fuse.c",
      "new_id": "cea9de61f1ddfe1de72da00dda33b6bce56b3cb8",
      "new_mode": 33188,
      "new_path": "block/export/fuse.c"
    }
  ]
}
