)]}'
{
  "commit": "09e099d4bafea3b15be003d548bdf94b4b6e0e17",
  "tree": "a4199338ad73e88c0863bbfc6604c4972055f16d",
  "parents": [
    "e4a683c899cd5a49f8d684a054c95bd115a0c005"
  ],
  "author": {
    "name": "Jerome Marchand",
    "email": "jmarchan@redhat.com",
    "time": "Wed Jan 05 16:57:38 2011 +0100"
  },
  "committer": {
    "name": "Jens Axboe",
    "email": "jaxboe@fusionio.com",
    "time": "Wed Jan 05 16:57:38 2011 +0100"
  },
  "message": "block: fix accounting bug on cross partition merges\n\n/proc/diskstats would display a strange output as follows.\n\n$ cat /proc/diskstats |grep sda\n   8       0 sda 90524 7579 102154 20464 0 0 0 0 0 14096 20089\n   8       1 sda1 19085 1352 21841 4209 0 0 0 0 4294967064 15689 4293424691\n                                                ~~~~~~~~~~\n   8       2 sda2 71252 3624 74891 15950 0 0 0 0 232 23995 1562390\n   8       3 sda3 54 487 2188 92 0 0 0 0 0 88 92\n   8       4 sda4 4 0 8 0 0 0 0 0 0 0 0\n   8       5 sda5 81 2027 2130 138 0 0 0 0 0 87 137\n\nIts reason is the wrong way of accounting hd_struct-\u003ein_flight. When a bio is\nmerged into a request belongs to different partition by ELEVATOR_FRONT_MERGE.\n\nThe detailed root cause is as follows.\n\nAssuming that there are two partition, sda1 and sda2.\n\n1. A request for sda2 is in request_queue. Hence sda1\u0027s hd_struct-\u003ein_flight\n   is 0 and sda2\u0027s one is 1.\n\n        | hd_struct-\u003ein_flight\n   ---------------------------\n   sda1 |          0\n   sda2 |          1\n   ---------------------------\n\n2. A bio belongs to sda1 is issued and is merged into the request mentioned on\n   step1 by ELEVATOR_BACK_MERGE. The first sector of the request is changed\n   from sda2 region to sda1 region. However the two partition\u0027s\n   hd_struct-\u003ein_flight are not changed.\n\n        | hd_struct-\u003ein_flight\n   ---------------------------\n   sda1 |          0\n   sda2 |          1\n   ---------------------------\n\n3. The request is finished and blk_account_io_done() is called. In this case,\n   sda2\u0027s hd_struct-\u003ein_flight, not a sda1\u0027s one, is decremented.\n\n        | hd_struct-\u003ein_flight\n   ---------------------------\n   sda1 |         -1\n   sda2 |          1\n   ---------------------------\n\nThe patch fixes the problem by caching the partition lookup\ninside the request structure, hence making sure that the increment\nand decrement will always happen on the same partition struct. This\nalso speeds up IO with accounting enabled, since it cuts down on\nthe number of lookups we have to do.\n\nAlso add a refcount to struct hd_struct to keep the partition in\nmemory as long as users exist. We use kref_test_and_get() to ensure\nwe don\u0027t add a reference to a partition which is going away.\n\nSigned-off-by: Jerome Marchand \u003cjmarchan@redhat.com\u003e\nSigned-off-by: Yasuaki Ishimatsu \u003cisimatu.yasuaki@jp.fujitsu.com\u003e\nCc: stable@kernel.org\nSigned-off-by: Jens Axboe \u003cjaxboe@fusionio.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "3689319a59749a709eaaafd8fc89725cebe10cfd",
      "old_mode": 33188,
      "old_path": "block/blk-core.c",
      "new_id": "500c080a6a6b36695e7d44a0f735c98544ac2e9a",
      "new_mode": 33188,
      "new_path": "block/blk-core.c"
    },
    {
      "type": "modify",
      "old_id": "77b7c26df6b50fea7a38ba0825d91583f1c4031c",
      "old_mode": 33188,
      "old_path": "block/blk-merge.c",
      "new_id": "b06b83b89d896d304a76b0357f3044d783f386f6",
      "new_mode": 33188,
      "new_path": "block/blk-merge.c"
    },
    {
      "type": "modify",
      "old_id": "16ccc0d2d5d367816700e7c2a88b773d3856810c",
      "old_mode": 33188,
      "old_path": "block/genhd.c",
      "new_id": "85c150598830b2378c1db970e228ed5261d24d3d",
      "new_mode": 33188,
      "new_path": "block/genhd.c"
    },
    {
      "type": "modify",
      "old_id": "bdf8d3cc95a4deeb89c5aab6a322f9824125862d",
      "old_mode": 33188,
      "old_path": "fs/partitions/check.c",
      "new_id": "48209f58522bc578e91fd6bea9a824a84247be20",
      "new_mode": 33188,
      "new_path": "fs/partitions/check.c"
    },
    {
      "type": "modify",
      "old_id": "aae86fd10c4f5dcea0eaf43cf6c39667a805dae4",
      "old_mode": 33188,
      "old_path": "include/linux/blkdev.h",
      "new_id": "482a7fd48831d6fd3d700931cbfa806d2efca7f4",
      "new_mode": 33188,
      "new_path": "include/linux/blkdev.h"
    },
    {
      "type": "modify",
      "old_id": "7a7b9c1644e4f26de810d54fd00a12302d56c927",
      "old_mode": 33188,
      "old_path": "include/linux/genhd.h",
      "new_id": "2ba2792a3dd4e1f1d02fb1f0039825d43afbe8ac",
      "new_mode": 33188,
      "new_path": "include/linux/genhd.h"
    }
  ]
}
