)]}'
{
  "commit": "b827e496c893de0c0f142abfaeb8730a2fd6b37f",
  "tree": "a86aecd5d811f9306b9662ceb5a5a45091b62b97",
  "parents": [
    "a5fc1abe438b87a9d128beebc377f78e2681a76d"
  ],
  "author": {
    "name": "Nick Piggin",
    "email": "npiggin@suse.de",
    "time": "Thu Apr 30 15:08:16 2009 -0700"
  },
  "committer": {
    "name": "Linus Torvalds",
    "email": "torvalds@linux-foundation.org",
    "time": "Sat May 02 15:36:09 2009 -0700"
  },
  "message": "mm: close page_mkwrite races\n\nChange page_mkwrite to allow implementations to return with the page\nlocked, and also change it\u0027s callers (in page fault paths) to hold the\nlock until the page is marked dirty.  This allows the filesystem to have\nfull control of page dirtying events coming from the VM.\n\nRather than simply hold the page locked over the page_mkwrite call, we\ncall page_mkwrite with the page unlocked and allow callers to return with\nit locked, so filesystems can avoid LOR conditions with page lock.\n\nThe problem with the current scheme is this: a filesystem that wants to\nassociate some metadata with a page as long as the page is dirty, will\nperform this manipulation in its -\u003epage_mkwrite.  It currently then must\nreturn with the page unlocked and may not hold any other locks (according\nto existing page_mkwrite convention).\n\nIn this window, the VM could write out the page, clearing page-dirty.  The\nfilesystem has no good way to detect that a dirty pte is about to be\nattached, so it will happily write out the page, at which point, the\nfilesystem may manipulate the metadata to reflect that the page is no\nlonger dirty.\n\nIt is not always possible to perform the required metadata manipulation in\n-\u003eset_page_dirty, because that function cannot block or fail.  The\nfilesystem may need to allocate some data structure, for example.\n\nAnd the VM cannot mark the pte dirty before page_mkwrite, because\npage_mkwrite is allowed to fail, so we must not allow any window where the\npage could be written to if page_mkwrite does fail.\n\nThis solution of holding the page locked over the 3 critical operations\n(page_mkwrite, setting the pte dirty, and finally setting the page dirty)\ncloses out races nicely, preventing page cleaning for writeout being\ninitiated in that window.  This provides the filesystem with a strong\nsynchronisation against the VM here.\n\n- Sage needs this race closed for ceph filesystem.\n- Trond for NFS (http://bugzilla.kernel.org/show_bug.cgi?id\u003d12913).\n- I need it for fsblock.\n- I suspect other filesystems may need it too (eg. btrfs).\n- I have converted buffer.c to the new locking. Even simple block allocation\n  under dirty pages might be susceptible to i_size changing under partial page\n  at the end of file (we also have a buffer.c-side problem here, but it cannot\n  be fixed properly without this patch).\n- Other filesystems (eg. NFS, maybe btrfs) will need to change their\n  page_mkwrite functions themselves.\n\n[ This also moves page_mkwrite another step closer to fault, which should\n  eventually allow page_mkwrite to be moved into -\u003efault, and thus avoiding a\n  filesystem calldown and page lock/unlock cycle in __do_fault. ]\n\n[akpm@linux-foundation.org: fix derefs of NULL -\u003emapping]\nCc: Sage Weil \u003csage@newdream.net\u003e\nCc: Trond Myklebust \u003ctrond.myklebust@fys.uio.no\u003e\nSigned-off-by: Nick Piggin \u003cnpiggin@suse.de\u003e\nCc: Valdis Kletnieks \u003cValdis.Kletnieks@vt.edu\u003e\nCc: \u003cstable@kernel.org\u003e\nSigned-off-by: Andrew Morton \u003cakpm@linux-foundation.org\u003e\nSigned-off-by: Linus Torvalds \u003ctorvalds@linux-foundation.org\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "76efe5b71d7d8f744739a129f4b5333b898acf5c",
      "old_mode": 33188,
      "old_path": "Documentation/filesystems/Locking",
      "new_id": "3120f8dd2c316c66347051a95d3edce1ad090d44",
      "new_mode": 33188,
      "new_path": "Documentation/filesystems/Locking"
    },
    {
      "type": "modify",
      "old_id": "b3e5be7514f5ce366b2a87262489bc88e1835a59",
      "old_mode": 33188,
      "old_path": "fs/buffer.c",
      "new_id": "aed297739eb0796d8c6212842003fb2976c5fba0",
      "new_mode": 33188,
      "new_path": "fs/buffer.c"
    },
    {
      "type": "modify",
      "old_id": "6a4ef0fd0711c4551333be01320a3d635d6cd20e",
      "old_mode": 33188,
      "old_path": "mm/memory.c",
      "new_id": "4126dd16778c36595af938988c9d8ec144d0f8aa",
      "new_mode": 33188,
      "new_path": "mm/memory.c"
    }
  ]
}
