)]}'
{
  "commit": "38c73044f5f4da2ef4339319b170e5e19f8dec87",
  "tree": "68f8bde12bf64eba00164cacdb895a164b5795d4",
  "parents": [
    "074cc1deec5dee63fcd5d966b36fa4f3765b50fc"
  ],
  "author": {
    "name": "Peter Staubach",
    "email": "staubach@redhat.com",
    "time": "Mon Aug 10 08:54:16 2009 -0400"
  },
  "committer": {
    "name": "Trond Myklebust",
    "email": "Trond.Myklebust@netapp.com",
    "time": "Mon Aug 10 08:54:16 2009 -0400"
  },
  "message": "NFS: read-modify-write page updating\n\nHi.\n\nI have a proposal for possibly resolving this issue.\n\nI believe that this situation occurs due to the way that the\nLinux NFS client handles writes which modify partial pages.\n\nThe Linux NFS client handles partial page modifications by\nallocating a page from the page cache, copying the data from\nthe user level into the page, and then keeping track of the\noffset and length of the modified portions of the page.  The\npage is not marked as up to date because there are portions\nof the page which do not contain valid file contents.\n\nWhen a read call comes in for a portion of the page, the\ncontents of the page must be read in the from the server.\nHowever, since the page may already contain some modified\ndata, that modified data must be written to the server\nbefore the file contents can be read back in the from server.\nAnd, since the writing and reading can not be done atomically,\nthe data must be written and committed to stable storage on\nthe server for safety purposes.  This means either a\nFILE_SYNC WRITE or a UNSTABLE WRITE followed by a COMMIT.\nThis has been discussed at length previously.\n\nThis algorithm could be described as modify-write-read.  It\nis most efficient when the application only updates pages\nand does not read them.\n\nMy proposed solution is to add a heuristic to decide whether\nto do this modify-write-read algorithm or switch to a read-\nmodify-write algorithm when initially allocating the page\nin the write system call path.  The heuristic uses the modes\nthat the file was opened with, the offset in the page to\nread from, and the size of the region to read.\n\nIf the file was opened for reading in addition to writing\nand the page would not be filled completely with data from\nthe user level, then read in the old contents of the page\nand mark it as Uptodate before copying in the new data.  If\nthe page would be completely filled with data from the user\nlevel, then there would be no reason to read in the old\ncontents because they would just be copied over.\n\nThis would optimize for applications which randomly access\nand update portions of files.  The linkage editor for the\nC compiler is an example of such a thing.\n\nI tested the attached patch by using rpmbuild to build the\ncurrent Fedora rawhide kernel.  The kernel without the\npatch generated about 269,500 WRITE requests.  The modified\nkernel containing the patch generated about 261,000 WRITE\nrequests.  Thus, about 8,500 fewer WRITE requests were\ngenerated.  I suspect that many of these additional\nWRITE requests were probably FILE_SYNC requests to WRITE\na single page, but I didn\u0027t test this theory.\n\nThe difference between this patch and the previous one was\nto remove the unneeded PageDirty() test.  I then retested to\nensure that the resulting system continued to behave as\ndesired.\n\n\tThanx...\n\n\t\tps\n\nSigned-off-by: Peter Staubach \u003cstaubach@redhat.com\u003e\nSigned-off-by: Trond Myklebust \u003cTrond.Myklebust@netapp.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "dfc89671dc94c5d28d98203a1ee70f141b1d4e11",
      "old_mode": 33188,
      "old_path": "fs/nfs/file.c",
      "new_id": "5021b75d2d1e65910177128b719efb20ec098077",
      "new_mode": 33188,
      "new_path": "fs/nfs/file.c"
    }
  ]
}
