diff options
Diffstat (limited to 'drivers/md/raid1.h')
| -rw-r--r-- | drivers/md/raid1.h | 123 |
1 files changed, 87 insertions, 36 deletions
diff --git a/drivers/md/raid1.h b/drivers/md/raid1.h index cbfdf1a6acd..9bebca7bff2 100644 --- a/drivers/md/raid1.h +++ b/drivers/md/raid1.h @@ -1,11 +1,15 @@ #ifndef _RAID1_H #define _RAID1_H -typedef struct mirror_info mirror_info_t; - -struct mirror_info { - mdk_rdev_t *rdev; +struct raid1_info { + struct md_rdev *rdev; sector_t head_position; + + /* When choose the best device for a read (read_balance()) + * we try to keep sequential reads one the same device + */ + sector_t next_seq_sect; + sector_t seq_start; }; /* @@ -14,58 +18,98 @@ struct mirror_info { * pool was allocated for, so they know how much to allocate and free. * mddev->raid_disks cannot be used, as it can change while a pool is active * These two datums are stored in a kmalloced struct. + * The 'raid_disks' here is twice the raid_disks in r1conf. + * This allows space for each 'real' device can have a replacement in the + * second half of the array. */ struct pool_info { - mddev_t *mddev; + struct mddev *mddev; int raid_disks; }; +struct r1conf { + struct mddev *mddev; + struct raid1_info *mirrors; /* twice 'raid_disks' to + * allow for replacements. + */ + int raid_disks; -typedef struct r1bio_s r1bio_t; + /* During resync, read_balancing is only allowed on the part + * of the array that has been resynced. 'next_resync' tells us + * where that is. + */ + sector_t next_resync; + + /* When raid1 starts resync, we divide array into four partitions + * |---------|--------------|---------------------|-------------| + * next_resync start_next_window end_window + * start_next_window = next_resync + NEXT_NORMALIO_DISTANCE + * end_window = start_next_window + NEXT_NORMALIO_DISTANCE + * current_window_requests means the count of normalIO between + * start_next_window and end_window. + * next_window_requests means the count of normalIO after end_window. + * */ + sector_t start_next_window; + int current_window_requests; + int next_window_requests; -struct r1_private_data_s { - mddev_t *mddev; - mirror_info_t *mirrors; - int raid_disks; - int last_used; - sector_t next_seq_sect; spinlock_t device_lock; + /* list of 'struct r1bio' that need to be processed by raid1d, + * whether to retry a read, writeout a resync or recovery + * block, or anything else. + */ struct list_head retry_list; - /* queue pending writes and submit them on unplug */ - struct bio_list pending_bio_list; - /* for use when syncing mirrors: */ + /* queue pending writes to be submitted on unplug */ + struct bio_list pending_bio_list; + int pending_count; + /* for use when syncing mirrors: + * We don't allow both normal IO and resync/recovery IO at + * the same time - resync/recovery can only happen when there + * is no other IO. So when either is active, the other has to wait. + * See more details description in raid1.c near raise_barrier(). + */ + wait_queue_head_t wait_barrier; spinlock_t resync_lock; 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 array_frozen; - wait_queue_head_t wait_barrier; + /* Set to 1 if a full sync is needed, (fresh device added). + * Cleared when a sync completes. + */ + int fullsync; + /* When the same as mddev->recovery_disabled we don't allow + * recovery to be attempted as we expect a read error. + */ + int recovery_disabled; + + + /* poolinfo contains information about the content of the + * mempools - it changes when the array grows or shrinks + */ struct pool_info *poolinfo; + mempool_t *r1bio_pool; + mempool_t *r1buf_pool; + /* temporary buffer to synchronous IO when attempting to repair + * a read error. + */ struct page *tmppage; - mempool_t *r1bio_pool; - mempool_t *r1buf_pool; /* When taking over an array from a different personality, we store * the new thread here until we fully activate the array. */ - struct mdk_thread_s *thread; + struct md_thread *thread; }; -typedef struct r1_private_data_s conf_t; - /* * this is our 'private' RAID1 bio. * @@ -73,7 +117,7 @@ typedef struct r1_private_data_s conf_t; * for this RAID1 operation, and about their status: */ -struct r1bio_s { +struct r1bio { atomic_t remaining; /* 'have we finished' count, * used from IRQ handlers */ @@ -81,9 +125,10 @@ struct r1bio_s { * in this BehindIO request */ sector_t sector; + sector_t start_next_window; int sectors; unsigned long state; - mddev_t *mddev; + struct mddev *mddev; /* * original bio going to /dev/mdx */ @@ -94,7 +139,9 @@ struct r1bio_s { int read_disk; struct list_head retry_list; - struct bitmap_update *bitmap_update; + /* Next two are only valid when R1BIO_BehindIO is set */ + struct bio_vec *behind_bvecs; + int behind_page_count; /* * if the IO is in WRITE direction, then multiple bios are used. * We choose the number when they are allocated. @@ -103,18 +150,15 @@ struct r1bio_s { /* DO NOT PUT ANY NEW FIELDS HERE - bios array is contiguously alloced*/ }; -/* when we get a read error on a read-only array, we redirect to another - * device without failing the first device, or trying to over-write to - * correct the read error. To keep track of bad blocks on a per-bio - * level, we store IO_BLOCKED in the appropriate 'bios' pointer - */ -#define IO_BLOCKED ((struct bio*)1) - /* bits for r1bio.state */ #define R1BIO_Uptodate 0 #define R1BIO_IsSync 1 #define R1BIO_Degraded 2 #define R1BIO_BehindIO 3 +/* Set ReadError on bios that experience a readerror so that + * raid1d knows what to do with them. + */ +#define R1BIO_ReadError 4 /* For write-behind requests, we call bi_end_io when * the last non-write-behind device completes, providing * any write was successful. Otherwise we call when @@ -123,5 +167,12 @@ struct r1bio_s { * Record that bi_end_io was called with this flag... */ #define R1BIO_Returned 6 +/* If a write for this request means we can clear some + * known-bad-block records, we set this flag + */ +#define R1BIO_MadeGood 7 +#define R1BIO_WriteError 8 + +extern int md_raid1_congested(struct mddev *mddev, int bits); #endif |
