)]}'
{
  "commit": "f5ce5c1742cd975c433056411be58283d4ede133",
  "tree": "0197d30ca4fdda0042decbf02b195fd0fe8dc26b",
  "parents": [
    "a36eabe54b21af768ee05b7e15ffab639d5de64d"
  ],
  "author": {
    "name": "Darrick J. Wong",
    "email": "djwong@kernel.org",
    "time": "Tue Jun 02 11:04:43 2026 -0700"
  },
  "committer": {
    "name": "Darrick J. Wong",
    "email": "djwong@kernel.org",
    "time": "Wed Jun 17 18:21:35 2026 -0700"
  },
  "message": "fuse: flush pending FUSE_RELEASE requests before sending FUSE_DESTROY\n\ngeneric/488 fails with fuse2fs in the following fashion:\n\ngeneric/488       _check_generic_filesystem: filesystem on /dev/sdf is inconsistent\n(see /var/tmp/fstests/generic/488.full for details)\n\nThis test opens a large number of files, unlinks them (which really just\nrenames them to fuse hidden files), closes the program, unmounts the\nfilesystem, and runs fsck to check that there aren\u0027t any inconsistencies\nin the filesystem.\n\nUnfortunately, the 488.full file shows that there are a lot of hidden\nfiles left over in the filesystem, with incorrect link counts.  Tracing\nfuse_request_* shows that there are a large number of FUSE_RELEASE\ncommands that are queued up on behalf of the unlinked files at the time\nthat fuse_conn_destroy calls fuse_abort_conn.  Had the connection not\naborted, the fuse server would have responded to the RELEASE commands by\nremoving the hidden files; instead they stick around.\n\nFor upper-level fuse servers that don\u0027t use fuseblk mode this isn\u0027t a\nproblem because libfuse responds to the connection going down by pruning\nits inode cache and calling the fuse server\u0027s -\u003erelease for any open\nfiles before calling the server\u0027s -\u003edestroy function.\n\nFor fuseblk servers this is a problem, however, because the kernel sends\nFUSE_DESTROY to the fuse server, and the fuse server has to write all of\nits pending changes to the block device before replying to the DESTROY\nrequest because the kernel releases its O_EXCL hold on the block device.\nThis means that the kernel must flush all pending FUSE_RELEASE requests\nbefore issuing FUSE_DESTROY.\n\nFor fuse-iomap servers this will also be a problem because iomap servers\nare expected to release all exclusively-held resources before unmount\nreturns from the kernel.\n\nCreate a function to push all the background requests to the queue\nbefore sending FUSE_DESTROY.  That way, all the pending file release\nevents are processed by the fuse server before it tears itself down, and\nwe don\u0027t end up with a corrupt filesystem.\n\nNote that multithreaded fuse servers will need to track the number of\nopen files and defer a FUSE_DESTROY request until that number reaches\nzero.  An earlier version of this patch made the kernel wait for the\nRELEASE acknowledgements before sending DESTROY, but the kernel people\nweren\u0027t comfortable with adding blocking waits to unmount.\n\nSigned-off-by: \"Darrick J. Wong\" \u003cdjwong@kernel.org\u003e\nReviewed-by: Joanne Koong \u003cjoannelkoong@gmail.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "c105aaf9ff5d7dc900f8c6dc6b28426d55677639",
      "old_mode": 33188,
      "old_path": "fs/fuse/dev.c",
      "new_id": "8e3cfdfd44555148c3f7046cf844ca1e694ee9fc",
      "new_mode": 33188,
      "new_path": "fs/fuse/dev.c"
    },
    {
      "type": "modify",
      "old_id": "17423d4e3cfa673b1377150fd469d20e168f952d",
      "old_mode": 33188,
      "old_path": "fs/fuse/fuse_i.h",
      "new_id": "f83bd090ca28ea2b2b93e65a9ec746e401091c97",
      "new_mode": 33188,
      "new_path": "fs/fuse/fuse_i.h"
    },
    {
      "type": "modify",
      "old_id": "deddfffb037fb83d84b413d098a40a735f94a629",
      "old_mode": 33188,
      "old_path": "fs/fuse/inode.c",
      "new_id": "21e55080faee2d7e9a8b4e59d3a0ac3135cd1457",
      "new_mode": 33188,
      "new_path": "fs/fuse/inode.c"
    }
  ]
}
