diff options
author | NeilBrown <neilb@suse.de> | 2011-12-23 00:17:54 +0100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2011-12-23 00:17:54 +0100 |
commit | 69335ef3bc5b766f34db2d688be1d35313138bca (patch) | |
tree | dcd87ffc4c97540d374a20de7380368e3679ac3b /drivers/md/raid10.h | |
parent | md/raid5: Mark device want_replacement when we see a write error. (diff) | |
download | linux-69335ef3bc5b766f34db2d688be1d35313138bca.tar.xz linux-69335ef3bc5b766f34db2d688be1d35313138bca.zip |
md/raid10: prepare data structures for handling replacement.
Allow each slot in the RAID10 to have 2 devices, the want_replacement
and the replacement.
Also an r10bio to have 2 bios, and for resync/recovery allocate the
second bio if there are any replacement devices.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid10.h')
-rw-r--r-- | drivers/md/raid10.h | 61 |
1 files changed, 37 insertions, 24 deletions
diff --git a/drivers/md/raid10.h b/drivers/md/raid10.h index 7facfdf841f4..7c615613c381 100644 --- a/drivers/md/raid10.h +++ b/drivers/md/raid10.h @@ -2,7 +2,7 @@ #define _RAID10_H struct mirror_info { - struct md_rdev *rdev; + struct md_rdev *rdev, *replacement; sector_t head_position; int recovery_disabled; /* matches * mddev->recovery_disabled @@ -18,12 +18,13 @@ struct r10conf { spinlock_t device_lock; /* geometry */ - int near_copies; /* number of copies laid out raid0 style */ + int near_copies; /* number of copies laid out + * raid0 style */ int far_copies; /* number of copies laid out * at large strides across drives */ - int far_offset; /* far_copies are offset by 1 stripe - * instead of many + int far_offset; /* far_copies are offset by 1 + * stripe instead of many */ int copies; /* near_copies * far_copies. * must be <= raid_disks @@ -34,10 +35,11 @@ struct r10conf { * 1 stripe. */ - sector_t dev_sectors; /* temp copy of mddev->dev_sectors */ + sector_t dev_sectors; /* temp copy of + * mddev->dev_sectors */ - int chunk_shift; /* shift from chunks to sectors */ - sector_t chunk_mask; + int chunk_shift; /* shift from chunks to sectors */ + sector_t chunk_mask; struct list_head retry_list; /* queue pending writes and submit them on unplug */ @@ -45,20 +47,22 @@ struct r10conf { int pending_count; spinlock_t resync_lock; - int nr_pending; - int nr_waiting; - int nr_queued; - int barrier; + int nr_pending; + int nr_waiting; + int nr_queued; + int barrier; sector_t next_resync; int fullsync; /* set to 1 if a full sync is needed, * (fresh device added). * Cleared when a sync completes. */ - + int have_replacement; /* There is at least one + * replacement device. + */ wait_queue_head_t wait_barrier; - mempool_t *r10bio_pool; - mempool_t *r10buf_pool; + mempool_t *r10bio_pool; + mempool_t *r10buf_pool; struct page *tmppage; /* When taking over an array from a different personality, we store @@ -98,11 +102,18 @@ struct r10bio { * When resyncing we also use one for each copy. * When reconstructing, we use 2 bios, one for read, one for write. * We choose the number when they are allocated. + * We sometimes need an extra bio to write to the replacement. */ struct { - struct bio *bio; - sector_t addr; - int devnum; + struct bio *bio; + union { + struct bio *repl_bio; /* used for resync and + * writes */ + struct md_rdev *rdev; /* used for reads + * (read_slot >= 0) */ + }; + sector_t addr; + int devnum; } devs[0]; }; @@ -121,17 +132,19 @@ struct r10bio { #define BIO_SPECIAL(bio) ((unsigned long)bio <= 2) /* bits for r10bio.state */ -#define R10BIO_Uptodate 0 -#define R10BIO_IsSync 1 -#define R10BIO_IsRecover 2 -#define R10BIO_Degraded 3 +enum r10bio_state { + R10BIO_Uptodate, + R10BIO_IsSync, + R10BIO_IsRecover, + R10BIO_Degraded, /* Set ReadError on bios that experience a read error * so that raid10d knows what to do with them. */ -#define R10BIO_ReadError 4 + R10BIO_ReadError, /* If a write for this request means we can clear some * known-bad-block records, we set this flag. */ -#define R10BIO_MadeGood 5 -#define R10BIO_WriteError 6 + R10BIO_MadeGood, + R10BIO_WriteError, +}; #endif |