1. 11 10月, 2011 4 次提交
  2. 07 10月, 2011 3 次提交
  3. 21 9月, 2011 1 次提交
    • N
      md: Avoid waking up a thread after it has been freed. · 01f96c0a
      NeilBrown 提交于
      Two related problems:
      
      1/ some error paths call "md_unregister_thread(mddev->thread)"
         without subsequently clearing ->thread.  A subsequent call
         to mddev_unlock will try to wake the thread, and crash.
      
      2/ Most calls to md_wakeup_thread are protected against the thread
         disappeared either by:
            - holding the ->mutex
            - having an active request, so something else must be keeping
              the array active.
         However mddev_unlock calls md_wakeup_thread after dropping the
         mutex and without any certainty of an active request, so the
         ->thread could theoretically disappear.
         So we need a spinlock to provide some protections.
      
      So change md_unregister_thread to take a pointer to the thread
      pointer, and ensure that it always does the required locking, and
      clears the pointer properly.
      Reported-by: N"Moshe Melnikov" <moshe@zadarastorage.com>
      Signed-off-by: NNeilBrown <neilb@suse.de>
      cc: stable@kernel.org
      01f96c0a
  4. 10 9月, 2011 1 次提交
  5. 28 7月, 2011 11 次提交
    • N
      md/raid1: factor several functions out or raid1d() · 62096bce
      NeilBrown 提交于
      raid1d is too big with several deep branches.
      So separate them out into their own functions.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      Reviewed-by: NNamhyung Kim <namhyung@gmail.com>
      62096bce
    • N
      md/raid1: improve handling of read failure during recovery. · 3a9f28a5
      NeilBrown 提交于
      If we cannot read a block from anywhere during recovery, there is
      now a better approach than just giving up.
      We can record a bad block on each device and keep going - being
      careful not to clear the bad block when a write succeeds as it might -
      it will be a write of incorrect data.
      
      We have now reached the state where - for raid1 - we only call
      md_error if md_set_badblocks has failed.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      Reviewed-by: NNamhyung Kim <namhyung@gmail.com>
      3a9f28a5
    • N
      md/raid1: record badblocks found during resync etc. · d8f05d29
      NeilBrown 提交于
      If we find a bad block while writing as part of resync/recovery we
      need to report that back to raid1d which must record the bad block,
      or fail the device.
      
      Similarly when fixing a read error, a further error should just
      record a bad block if possible rather than failing the device.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      Reviewed-by: NNamhyung Kim <namhyung@gmail.com>
      d8f05d29
    • N
      md/raid1: Handle write errors by updating badblock log. · cd5ff9a1
      NeilBrown 提交于
      When we get a write error (in the data area, not in metadata),
      update the badblock log rather than failing the whole device.
      
      As the write may well be many blocks, we trying writing each
      block individually and only log the ones which fail.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      Reviewed-by: NNamhyung Kim <namhyung@gmail.com>
      cd5ff9a1
    • N
      md/raid1: store behind-write pages in bi_vecs. · 2ca68f5e
      NeilBrown 提交于
      When performing write-behind we allocate pages to store the data
      during write.
      Previously we just keep a list of pages.  Now we keep a list of
      bi_vec which includes offset and size.
      This means that the r1bio has complete information to create a new
      bio which will be needed for retrying after write errors.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      Reviewed-by: NNamhyung Kim <namhyung@gmail.com>
      2ca68f5e
    • N
      md/raid1: clear bad-block record when write succeeds. · 4367af55
      NeilBrown 提交于
      If we succeed in writing to a block that was recorded as
      being bad, we clear the bad-block record.
      
      This requires some delayed handling as the bad-block-list update has
      to happen in process-context.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      Reviewed-by: NNamhyung Kim <namhyung@gmail.com>
      4367af55
    • N
      md/raid1: avoid writing to known-bad blocks on known-bad drives. · 1f68f0c4
      NeilBrown 提交于
      If we have seen any write error on a drive, then don't write to
      any known-bad blocks on that drive.
      If necessary, we divide the write request up into pieces just
      like we do for reads, so each piece is either all written or
      all not written to any given drive.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      Reviewed-by: NNamhyung Kim <namhyung@gmail.com>
      1f68f0c4
    • N
      md: make it easier to wait for bad blocks to be acknowledged. · de393cde
      NeilBrown 提交于
      It is only safe to choose not to write to a bad block if that bad
      block is safely recorded in metadata - i.e. if it has been
      'acknowledged'.
      
      If it hasn't we need to wait for the acknowledgement.
      
      We support that using rdev->blocked wait and
      md_wait_for_blocked_rdev by introducing a new device flag
      'BlockedBadBlock'.
      
      This flag is only advisory.
      It is cleared whenever we acknowledge a bad block, so that a waiter
      can re-check the particular bad blocks that it is interested it.
      
      It should be set by a caller when they find they need to wait.
      This (set after test) is inherently racy, but as
      md_wait_for_blocked_rdev already has a timeout, losing the race will
      have minimal impact.
      
      When we clear "Blocked" was also clear "BlockedBadBlocks" incase it
      was set incorrectly (see above race).
      
      We also modify the way we manage 'Blocked' to fit better with the new
      handling of 'BlockedBadBlocks' and to make it consistent between
      externally managed and internally managed metadata.   This requires
      that each raidXd loop checks if the metadata needs to be written and
      triggers a write (md_check_recovery) if needed.  Otherwise a queued
      write request might cause raidXd to wait for the metadata to write,
      and only that thread can write it.
      
      Before writing metadata, we set FaultRecorded for all devices that
      are Faulty, then after writing the metadata we clear Blocked for any
      device for which the Fault was certainly Recorded.
      
      The 'faulty' device flag now appears in sysfs if the device is faulty
      *or* it has unacknowledged bad blocks.  So user-space which does not
      understand bad blocks can continue to function correctly.
      User space which does, should not assume a device is faulty until it
      sees the 'faulty' flag, and then sees the list of unacknowledged bad
      blocks is empty.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      de393cde
    • N
      md/raid1: avoid reading known bad blocks during resync · 06f60385
      NeilBrown 提交于
      When performing resync/etc, keep the size of the request
      small enough that it doesn't overlap any known bad blocks.
      Devices with badblocks at the start of the request are completely
      excluded.
      If there is nowhere to read from due to bad blocks, record
      a bad block on each target device.
      
      Now that we never read from known-bad-blocks we can allow devices with
      known-bad-blocks into a RAID1.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      06f60385
    • N
      md/raid1: avoid reading from known bad blocks. · d2eb35ac
      NeilBrown 提交于
      Now that we have a bad block list, we should not read from those
      blocks.
      There are several main parts to this:
        1/ read_balance needs to check for bad blocks, and return not only
           the chosen device, but also how many good blocks are available
           there.
        2/ fix_read_error needs to avoid trying to read from bad blocks.
        3/ read submission must be ready to issue multiple reads to
           different devices as different bad blocks on different devices
           could mean that a single large read cannot be served by any one
           device, but can still be served by the array.
           This requires keeping count of the number of outstanding requests
           per bio.  This count is stored in 'bi_phys_segments'
        4/ retrying a read needs to also be ready to submit a smaller read
           and queue another request for the rest.
      
      This does not yet handle bad blocks when reading to perform resync,
      recovery, or check.
      
      'md_trim_bio' will also be used for RAID10, so put it in md.c and
      export it.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      d2eb35ac
    • N
      md: don't allow arrays to contain devices with bad blocks. · 34b343cf
      NeilBrown 提交于
      As no personality understand bad block lists yet, we must
      reject any device that is known to contain bad blocks.
      As the personalities get taught, these tests can be removed.
      
      This only applies to raid1/raid5/raid10.
      For linear/raid0/multipath/faulty the whole concept of bad blocks
      doesn't mean anything so there is no point adding the checks.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      Reviewed-by: NNamhyung Kim <namhyung@gmail.com>
      34b343cf
  6. 27 7月, 2011 5 次提交
  7. 08 6月, 2011 1 次提交
  8. 11 5月, 2011 6 次提交
    • N
      md: allow resync_start to be set while an array is active. · b098636c
      NeilBrown 提交于
      The sysfs attribute 'resync_start' (known internally as recovery_cp),
      records where a resync is up to.  A value of 0 means the array is
      not known to be in-sync at all.  A value of MaxSector means the array
      is believed to be fully in-sync.
      
      When the size of member devices of an array (RAID1,RAID4/5/6) is
      increased, the array can be increased to match.  This process sets
      resync_start to the old end-of-device offset so that the new part of
      the array gets resynced.
      
      However with RAID1 (and RAID6) a resync is not technically necessary
      and may be undesirable.  So it would be good if the implied resync
      after the array is resized could be avoided.
      
      So: change 'resync_start' so the value can be changed while the array
      is active, and as a precaution only allow it to be changed while
      resync/recovery is 'frozen'.  Changing it once resync has started is
      not going to be useful anyway.
      
      This allows the array to be resized without a resync by:
        write 'frozen' to 'sync_action'
        write new size to 'component_size' (this will set resync_start)
        write 'none' to 'resync_start'
        write 'idle' to 'sync_action'.
      
      Also slightly improve some tests on recovery_cp when resizing
      raid1/raid5.  Now that an arbitrary value could be set we should be
      more careful in our tests.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      b098636c
    • N
      md/raid1: improve handling of pages allocated for write-behind. · af6d7b76
      NeilBrown 提交于
      The current handling and freeing of these pages is a bit fragile.
      We only keep the list of allocated pages in each bio, so we need to
      still have a valid bio when freeing the pages, which is a bit clumsy.
      
      So simply store the allocated page list in the r1_bio so it can easily
      be found and freed when we are finished with the r1_bio.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      af6d7b76
    • N
      md/raid1: try fix_sync_read_error before process_checks. · 7ca78d57
      NeilBrown 提交于
      If we get a read error during resync/recovery we current repeat with
      single-page reads to find out just where the error is, and possibly
      read each page from a different device.
      
      With check/repair we don't currently do that, we just fail.
      However it is possible that while all devices fail on the large 64K
      read, we might be able to satisfy each 4K from one device or another.
      
      So call fix_sync_read_error before process_checks to maximise the
      chance of finding good data and writing it out to the devices with
      read errors.
      
      For this to work, we need to set the 'uptodate' flags properly after
      fix_sync_read_error has succeeded.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      7ca78d57
    • N
      md/raid1: tidy up new functions: process_checks and fix_sync_read_error. · 78d7f5f7
      NeilBrown 提交于
      These changes are mostly cosmetic:
      
      1/ change mddev->raid_disks to conf->raid_disks because the later is
         technically safer, though in current practice it doesn't matter in
         this particular context.
      2/ Rearrange two for / if loops to have an early 'continue' so the
         body of the 'if' doesn't need to be indented so much.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      78d7f5f7
    • N
      md/raid1: split out two sub-functions from sync_request_write · a68e5870
      NeilBrown 提交于
      sync_request_write is too big and too deep.
      So split out two self-contains bits of functionality into separate
      function.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      a68e5870
    • N
      md/raid1: clean up read_balance. · 76073054
      NeilBrown 提交于
      read_balance has two loops which both look for a 'best'
      device based on slightly different criteria.
      This is clumsy and makes is hard to add extra criteria.
      
      So replace it all with a single loop that combines everything.
      Signed-off-by: NNeilBrown <neilb@suse.de>
      76073054
  9. 18 4月, 2011 2 次提交
  10. 17 3月, 2011 1 次提交
  11. 10 3月, 2011 1 次提交
  12. 21 2月, 2011 1 次提交
    • N
      md: avoid spinlock problem in blk_throtl_exit · da9cf505
      NeilBrown 提交于
      blk_throtl_exit assumes that ->queue_lock still exists,
      so make sure that it does.
      To do this, we stop redirecting ->queue_lock to conf->device_lock
      and leave it pointing where it is initialised - __queue_lock.
      
      As the blk_plug functions check the ->queue_lock is held, we now
      take that spin_lock explicitly around the plug functions.  We don't
      need the locking, just the warning removal.
      
      This is needed for any kernel with the blk_throtl code, which is
      which is 2.6.37 and later.
      
      Cc: stable@kernel.org
      Signed-off-by: NNeilBrown <neilb@suse.de>
      da9cf505
  13. 14 1月, 2011 2 次提交
  14. 24 11月, 2010 1 次提交
    • N
      md/raid1: really fix recovery looping when single good device fails. · 8f9e0ee3
      NeilBrown 提交于
      Commit 4044ba58 supposedly fixed a
      problem where if a raid1 with just one good device gets a read-error
      during recovery, the recovery would abort and immediately restart in
      an infinite loop.
      
      However it depended on raid1_remove_disk removing the spare device
      from the array.  But that does not happen in this case.  So add a test
      so that in the 'recovery_disabled' case, the device will be removed.
      
      This suitable for any kernel since 2.6.29 which is when
      recovery_disabled was introduced.
      
      Cc: stable@kernel.org
      Reported-by: NSebastian Färber <faerber@gmail.com>
      Signed-off-by: NNeilBrown <neilb@suse.de>
      8f9e0ee3