)]}'
{
  "commit": "cbc6bba755a0925f541f57a4611444a9b48f8ead",
  "tree": "e066108de5267796c95b56c88d12fb056dfe25df",
  "parents": [
    "63e90fcc18072638a62196caae93de66fc6cbc37"
  ],
  "author": {
    "name": "Al Viro",
    "email": "viro@zeniv.linux.org.uk",
    "time": "Wed May 14 20:50:06 2025 -0400"
  },
  "committer": {
    "name": "Al Viro",
    "email": "viro@zeniv.linux.org.uk",
    "time": "Sat May 24 14:29:46 2025 -0400"
  },
  "message": "Rewrite of propagate_umount()\n\nThe variant currently in the tree has problems; trying to prove\ncorrectness has caught at least one class of bugs (reparenting\nthat ends up moving the visible location of reparented mount, due\nto not excluding some of the counterparts on propagation that\nshould\u0027ve been included).\n\nI tried to prove that it\u0027s the only bug there; I\u0027m still not sure\nwhether it is.  If anyone can reconstruct and write down an analysis\nof the mainline implementation, I\u0027ll gladly review it; as it is,\nI ended up doing a different implementation.  Candidate collection\nphase is similar, but trimming the set down until it satisfies the\nconstraints turned out pretty different.\n\nI hoped to do transformation as a massage series, but that turns out\nto be too convoluted.  So it\u0027s a single patch replacing propagate_umount()\nand friends in one go, with notes and analysis in D/f/propagate_umount.txt\n(in addition to inline comments).\n\nAs far I can tell, it is provably correct and provably linear by the number\nof mounts we need to look at in order to decide what should be unmounted.\nIt even builds and seems to survive testing...\n\nAnother nice thing that fell out of that is that -\u003emnt_umounting is no longer\nneeded.\n\nCompared to the first version:\n\t* explicit MNT_UMOUNT_CANDIDATE flag for is_candidate()\n\t* trim_ancestors() only clears that flag, leaving the suckers on list\n\t* trim_one() and handle_locked() take the stuff with flag cleared off\nthe list.  That allows to iterate with list_for_each_entry_safe() when calling\ntrim_one() - it removes at most one element from the list now.\n\t* no globals - I didn\u0027t bother with any kind of context, not worth it.\n\n\t* Notes updated accordingly; I have not touch the terms yet.\n\nSigned-off-by: Al Viro \u003cviro@zeniv.linux.org.uk\u003e\n",
  "tree_diff": [
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "5b48540b4059eec1a569a88763683bb464089c6c",
      "new_mode": 33188,
      "new_path": "Documentation/filesystems/propagate_umount.txt"
    },
    {
      "type": "modify",
      "old_id": "ad7173037924a86c8302fee2219e02163e5c2c7a",
      "old_mode": 33188,
      "old_path": "fs/mount.h",
      "new_id": "ab129c8d90c2804c46792c12eaf749b0adde7268",
      "new_mode": 33188,
      "new_path": "fs/mount.h"
    },
    {
      "type": "modify",
      "old_id": "623cd110076dcd97d5c9e94a2de2c9f6d6faf944",
      "old_mode": 33188,
      "old_path": "fs/namespace.c",
      "new_id": "7fc4617690707e78534962d804d38b8d6613ef73",
      "new_mode": 33188,
      "new_path": "fs/namespace.c"
    },
    {
      "type": "modify",
      "old_id": "ffd429b760d5d422477c524b3ef14d825f131fb1",
      "old_mode": 33188,
      "old_path": "fs/pnode.c",
      "new_id": "8eaa6640d18c9cf9e8b8771ea7106a56e58e3752",
      "new_mode": 33188,
      "new_path": "fs/pnode.c"
    },
    {
      "type": "modify",
      "old_id": "34b6247af01d925b9d5523a9fa58e70ddc290856",
      "old_mode": 33188,
      "old_path": "fs/pnode.h",
      "new_id": "d84a397bfd4350070379e57872f309b4bcfc4f20",
      "new_mode": 33188,
      "new_path": "fs/pnode.h"
    },
    {
      "type": "modify",
      "old_id": "dcc17ce8a959e035d72b9002268554912cf57514",
      "old_mode": 33188,
      "old_path": "include/linux/mount.h",
      "new_id": "33af9c4058fa6994730dde42a543a68b2c540b1c",
      "new_mode": 33188,
      "new_path": "include/linux/mount.h"
    }
  ]
}
