)]}'
{
  "commit": "2e93ccc1933d08d32d9bde3784c3823e67b9b030",
  "tree": "1e8ad6a6444fc0a568e35f19628c89cdef9ad512",
  "parents": [
    "81fdb096dbcedcc3b94c7e47b59362b5214891e2"
  ],
  "author": {
    "name": "Kiyoshi Ueda",
    "email": "k-ueda@ct.jp.nec.com",
    "time": "Fri Dec 08 02:41:09 2006 -0800"
  },
  "committer": {
    "name": "Linus Torvalds",
    "email": "torvalds@woody.osdl.org",
    "time": "Fri Dec 08 08:29:09 2006 -0800"
  },
  "message": "[PATCH] dm: suspend: add noflush pushback\n\nIn device-mapper I/O is sometimes queued within targets for later processing.\nFor example the multipath target can be configured to store I/O when no paths\nare available instead of returning it -EIO.\n\nThis patch allows the device-mapper core to instruct a target to transfer the\ncontents of any such in-target queue back into the core.  This frees up the\nresources used by the target so the core can replace that target with an\nalternative one and then resend the I/O to it.  Without this patch the only\nway to change the target in such circumstances involves returning the I/O with\nan error back to the filesystem/application.  In the multipath case, this\npatch will let us add new paths for existing I/O to try after all the existing\npaths have failed.\n\n    DMF_NOFLUSH_SUSPENDING\n    ----------------------\n\nIf the DM_NOFLUSH_FLAG ioctl option is specified at suspend time, the\nDMF_NOFLUSH_SUSPENDING flag is set in md-\u003eflags during dm_suspend().  It\nis always cleared before dm_suspend() returns.\n\nThe flag must be visible while the target is flushing pending I/Os so it\nis set before presuspend where the flush starts and unset after the wait\nfor md-\u003epending where the flush ends.\n\nTarget drivers can check this flag by calling dm_noflush_suspending().\n\n    DM_MAPIO_REQUEUE / DM_ENDIO_REQUEUE\n    -----------------------------------\n\nA target\u0027s map() function can now return DM_MAPIO_REQUEUE to request the\ndevice mapper core queue the bio.\n\nSimilarly, a target\u0027s end_io() function can return DM_ENDIO_REQUEUE to request\nthe same.  This has been labelled \u0027pushback\u0027.\n\nThe __map_bio() and clone_endio() functions in the core treat these return\nvalues as errors and call dec_pending() to end the I/O.\n\n    dec_pending\n    -----------\n\ndec_pending() saves the pushback request in struct dm_io-\u003eerror.  Once all\nthe split clones have ended, dec_pending() will put the original bio on\nthe md-\u003epushback list.  Note that this supercedes any I/O errors.\n\nIt is possible for the suspend with DM_NOFLUSH_FLAG to be aborted while\nin progress (e.g. by user interrupt).  dec_pending() checks for this and\nreturns -EIO if it happened.\n\n    pushdback list and pushback_lock\n    --------------------------------\n\nThe bio is queued on md-\u003epushback temporarily in dec_pending(), and after\nall pending I/Os return, md-\u003epushback is merged into md-\u003edeferred in\ndm_suspend() for re-issuing at resume time.\n\nmd-\u003epushback_lock protects md-\u003epushback.\nThe lock should be held with irq disabled because dec_pending() can be\ncalled from interrupt context.\n\nQueueing bios to md-\u003epushback in dec_pending() must be done atomically\nwith the check for DMF_NOFLUSH_SUSPENDING flag.  So md-\u003epushback_lock is\nheld when checking the flag.  Otherwise dec_pending() may queue a bio to\nmd-\u003epushback after the interrupted dm_suspend() flushes md-\u003epushback.\nThen the bio would be left in md-\u003epushback.\n\nFlag setting in dm_suspend() can be done without md-\u003epushback_lock because\nthe flag is checked only after presuspend and the set value is already\nmade visible via the target\u0027s presuspend function.\n\nThe flag can be checked without md-\u003epushback_lock (e.g. the first part of\nthe dec_pending() or target drivers), because the flag is checked again\nwith md-\u003epushback_lock held when the bio is really queued to md-\u003epushback\nas described above.  So even if the flag is cleared after the lockless\ncheckings, the bio isn\u0027t left in md-\u003epushback but returned to applications\nwith -EIO.\n\n    Other notes on the current patch\n    --------------------------------\n\n- md-\u003epushback is added to the struct mapped_device instead of using\n  md-\u003edeferred directly because md-\u003eio_lock which protects md-\u003edeferred is\n  rw_semaphore and can\u0027t be used in interrupt context like dec_pending(),\n  and md-\u003eio_lock protects the DMF_BLOCK_IO flag of md-\u003eflags too.\n\n- Don\u0027t issue lock_fs() in dm_suspend() if the DM_NOFLUSH_FLAG\n  ioctl option is specified, because I/Os generated by lock_fs() would be\n  pushed back and never return if there were no valid devices.\n\n- If an error occurs in dm_suspend() after the DMF_NOFLUSH_SUSPENDING\n  flag is set, md-\u003epushback must be flushed because I/Os may be queued to\n  the list already.  (flush_and_out label in dm_suspend())\n\n    Test results\n    ------------\n\nI have tested using multipath target with the next patch.\n\nThe following tests are for regression/compatibility:\n  - I/Os succeed when valid paths exist;\n  - I/Os fail when there are no valid paths and queue_if_no_path is not\n    set;\n  - I/Os are queued in the multipath target when there are no valid paths and\n    queue_if_no_path is set;\n  - The queued I/Os above fail when suspend is issued without the\n    DM_NOFLUSH_FLAG ioctl option.  I/Os spanning 2 multipath targets also\n    fail.\n\nThe following tests are for the normal code path of new pushback feature:\n  - Queued I/Os in the multipath target are flushed from the target\n    but don\u0027t return when suspend is issued with the DM_NOFLUSH_FLAG\n    ioctl option;\n  - The I/Os above are queued in the multipath target again when\n    resume is issued without path recovery;\n  - The I/Os above succeed when resume is issued after path recovery\n    or table load;\n  - Queued I/Os in the multipath target succeed when resume is issued\n    with the DM_NOFLUSH_FLAG ioctl option after table load. I/Os\n    spanning 2 multipath targets also succeed.\n\nThe following tests are for the error paths of the new pushback feature:\n  - When the bdget_disk() fails in dm_suspend(), the\n    DMF_NOFLUSH_SUSPENDING flag is cleared and I/Os already queued to the\n    pushback list are flushed properly.\n  - When suspend with the DM_NOFLUSH_FLAG ioctl option is interrupted,\n      o I/Os which had already been queued to the pushback list\n        at the time don\u0027t return, and are re-issued at resume time;\n      o I/Os which hadn\u0027t been returned at the time return with EIO.\n\nSigned-off-by: Kiyoshi Ueda \u003ck-ueda@ct.jp.nec.com\u003e\nSigned-off-by: Jun\u0027ichi Nomura \u003cj-nomura@ce.jp.nec.com\u003e\nSigned-off-by: Alasdair G Kergon \u003cagk@redhat.com\u003e\nCc: dm-devel@redhat.com\nSigned-off-by: Andrew Morton \u003cakpm@osdl.org\u003e\nSigned-off-by: Linus Torvalds \u003ctorvalds@osdl.org\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "bbf4615f0e30d792990208325fa9fa48580ce879",
      "old_mode": 33188,
      "old_path": "drivers/md/dm-bio-list.h",
      "new_id": "da4349649f7f2cd5c7c6d628f40d8bf1a1463b84",
      "new_mode": 33188,
      "new_path": "drivers/md/dm-bio-list.h"
    },
    {
      "type": "modify",
      "old_id": "d8544e1a4c1f96a0f79490226d833880ee3c38a5",
      "old_mode": 33188,
      "old_path": "drivers/md/dm.c",
      "new_id": "fe7c56e104359ce95ce8b34143542535d030c78c",
      "new_mode": 33188,
      "new_path": "drivers/md/dm.c"
    },
    {
      "type": "modify",
      "old_id": "c307ca9a4c332db76af2caf02aeaf94d4a097376",
      "old_mode": 33188,
      "old_path": "drivers/md/dm.h",
      "new_id": "2f796b1436b2a6f898fac79f05cf4bee036d04f0",
      "new_mode": 33188,
      "new_path": "drivers/md/dm.h"
    },
    {
      "type": "modify",
      "old_id": "2e5c42346c381a0857963ee79aacffec97eaff9c",
      "old_mode": 33188,
      "old_path": "include/linux/device-mapper.h",
      "new_id": "499f5373e2134d7a1a0fa8b9a84bddc3ad23b26b",
      "new_mode": 33188,
      "new_path": "include/linux/device-mapper.h"
    }
  ]
}
