1. 28 Jul, 2011 10 commits
    • NeilBrown's avatar
      md: make it easier to wait for bad blocks to be acknowledged. · de393cde
      NeilBrown authored
      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: default avatarNeilBrown <neilb@suse.de>
      de393cde
    • NeilBrown's avatar
      md: add 'write_error' flag to component devices. · d7a9d443
      NeilBrown authored
      If a device has ever seen a write error, we will want to handle
      known-bad-blocks differently.
      So create an appropriate state flag and export it via sysfs.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Reviewed-by: default avatarNamhyung Kim <namhyung@gmail.com>
      d7a9d443
    • NeilBrown's avatar
      md/raid1: avoid reading known bad blocks during resync · 06f60385
      NeilBrown authored
      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: default avatarNeilBrown <neilb@suse.de>
      06f60385
    • NeilBrown's avatar
      md/raid1: avoid reading from known bad blocks. · d2eb35ac
      NeilBrown authored
      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: default avatarNeilBrown <neilb@suse.de>
      d2eb35ac
    • NeilBrown's avatar
      md: Disable bad blocks and v0.90 metadata. · 9f2f3830
      NeilBrown authored
      v0.90 metadata cannot record bad blocks, so when loading metadata
      for such a device, set shift to -1.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      9f2f3830
    • NeilBrown's avatar
      md: load/store badblock list from v1.x metadata · 2699b672
      NeilBrown authored
      Space must have been allocated when array was created.
      A feature flag is set when the badblock list is non-empty, to
      ensure old kernels don't load and trust the whole device.
      
      We only update the on-disk badblocklist when it has changed.
      If the badblocklist (or other metadata) is stored on a bad block, we
      don't cope very well.
      
      If metadata has no room for bad block, flag bad-blocks as disabled,
      and do the same for 0.90 metadata.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      2699b672
    • NeilBrown's avatar
      md: don't allow arrays to contain devices with bad blocks. · 34b343cf
      NeilBrown authored
      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: default avatarNeilBrown <neilb@suse.de>
      Reviewed-by: default avatarNamhyung Kim <namhyung@gmail.com>
      34b343cf
    • Namhyung Kim's avatar
      md: add documentation for bad block log · 6e0d2d03
      Namhyung Kim authored
      Previous patch in the bad block series added new sysfs interfaces
      ([unacknowledged_]bad_blocks) for each rdev without documentation.
      Add it.
      Signed-off-by: default avatarNamhyung Kim <namhyung@gmail.com>
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      6e0d2d03
    • NeilBrown's avatar
      md/bad-block-log: add sysfs interface for accessing bad-block-log. · 16c791a5
      NeilBrown authored
      This can show the log (providing it fits in one page) and
      allows bad blocks to be 'acknowledged' meaning that they
      have safely been recorded in metadata.
      
      Clearing bad blocks is not allowed via sysfs (except for
      code testing).  A bad block can only be cleared when
      a write to the block succeeds.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Reviewed-by: default avatarNamhyung Kim <namhyung@gmail.com>
      16c791a5
    • NeilBrown's avatar
      md: beginnings of bad block management. · 2230dfe4
      NeilBrown authored
      This the first step in allowing md to track bad-blocks per-device so
      that we can fail individual blocks rather than the whole device.
      
      This patch just adds a data structure for recording bad blocks, with
      routines to add, remove, search the list.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Reviewed-by: default avatarNamhyung Kim <namhyung@gmail.com>
      2230dfe4
  2. 27 Jul, 2011 25 commits
  3. 26 Jul, 2011 5 commits
    • NeilBrown's avatar
      md/raid5: move stripe_head_state and more code into handle_stripe. · cc94015a
      NeilBrown authored
      By defining the 'stripe_head_state' in 'handle_stripe', we can move
      some common code out of handle_stripe[56]() and into handle_stripe.
      
      The means that all accesses for stripe_head_state in handle_stripe[56]
      need to be 's->' instead of 's.', but the compiler should inline
      those functions and just use a direct stack reference, and future
      patches while hoist most of this code up into handle_stripe()
      so we will revert to "s.".
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Reviewed-by: default avatarNamhyung Kim <namhyung@gmail.com>
      cc94015a
    • NeilBrown's avatar
      md/raid5: add some more fields to stripe_head_state · c5709ef6
      NeilBrown authored
      Adding these three fields will allow more common code to be moved
      to handle_stripe()
      
      struct field rearrangement by Namhyung Kim.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Reviewed-by: default avatarNamhyung Kim <namhyung@gmail.com>
      c5709ef6
    • NeilBrown's avatar
      md/raid5: unify stripe_head_state and r6_state · f2b3b44d
      NeilBrown authored
      'struct stripe_head_state' stores state about the 'current' stripe
      that is passed around while handling the stripe.
      For RAID6 there is an extension structure: r6_state, which is also
      passed around.
      There is no value in keeping these separate, so move the fields from
      the latter into the former.
      
      This means that all code now needs to treat s->failed_num as an small
      array, but this is a small cost.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Reviewed-by: default avatarNamhyung Kim <namhyung@gmail.com>
      f2b3b44d
    • NeilBrown's avatar
      md/raid5: move common code into handle_stripe · 82e5a171
      NeilBrown authored
      There is common code at the start of handle_stripe5 and
      handle_stripe6.  Move it into handle_stripe.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Reviewed-by: default avatarNamhyung Kim <namhyung@gmail.com>
      82e5a171
    • NeilBrown's avatar
      md/raid5: replace sh->lock with an 'active' flag. · c4c1663b
      NeilBrown authored
      sh->lock is now mainly used to ensure that two threads aren't running
      in the locked part of handle_stripe[56] at the same time.
      
      That can more neatly be achieved with an 'active' flag which we set
      while running handle_stripe.  If we find the flag is set, we simply
      requeue the stripe for later by setting STRIPE_HANDLE.
      
      For safety we take ->device_lock while examining the state of the
      stripe and creating a summary in 'stripe_head_state / r6_state'.
      This possibly isn't needed but as shared fields like ->toread,
      ->towrite are checked it is safer for now at least.
      
      We leave the label after the old 'unlock' called "unlock" because it
      will disappear in a few patches, so renaming seems pointless.
      
      This leaves the stripe 'locked' for longer as we clear STRIPE_ACTIVE
      later, but that is not a problem.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Reviewed-by: default avatarNamhyung Kim <namhyung@gmail.com>
      c4c1663b