diff options
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 386 |
1 files changed, 171 insertions, 215 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index ac5e8b57e50..297e2609217 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -47,6 +47,7 @@ #include <linux/kthread.h> #include <linux/raid/pq.h> #include <linux/async_tx.h> +#include <linux/module.h> #include <linux/async.h> #include <linux/seq_file.h> #include <linux/cpu.h> @@ -70,7 +71,11 @@ #define NR_HASH (PAGE_SIZE / sizeof(struct hlist_head)) #define HASH_MASK (NR_HASH - 1) -#define stripe_hash(conf, sect) (&((conf)->stripe_hashtbl[((sect) >> STRIPE_SHIFT) & HASH_MASK])) +static inline struct hlist_head *stripe_hash(struct r5conf *conf, sector_t sect) +{ + int hash = (sect >> STRIPE_SHIFT) & HASH_MASK; + return &conf->stripe_hashtbl[hash]; +} /* bio's attached to a stripe+device for I/O are linked together in bi_sector * order without overlap. There may be several bio's per stripe+device, and @@ -78,24 +83,17 @@ * When walking this list for a particular stripe+device, we must never proceed * beyond a bio that extends past this device, as the next bio might no longer * be valid. - * This macro is used to determine the 'next' bio in the list, given the sector + * This function is used to determine the 'next' bio in the list, given the sector * of the current stripe+device */ -#define r5_next_bio(bio, sect) ( ( (bio)->bi_sector + ((bio)->bi_size>>9) < sect + STRIPE_SECTORS) ? (bio)->bi_next : NULL) -/* - * The following can be used to debug the driver - */ -#define RAID5_PARANOIA 1 -#if RAID5_PARANOIA && defined(CONFIG_SMP) -# define CHECK_DEVLOCK() assert_spin_locked(&conf->device_lock) -#else -# define CHECK_DEVLOCK() -#endif - -#ifdef DEBUG -#define inline -#define __inline__ -#endif +static inline struct bio *r5_next_bio(struct bio *bio, sector_t sector) +{ + int sectors = bio->bi_size >> 9; + if (bio->bi_sector + sectors < sector + STRIPE_SECTORS) + return bio->bi_next; + else + return NULL; +} /* * We maintain a biased count of active stripes in the bottom 16 bits of @@ -183,7 +181,7 @@ static void return_io(struct bio *return_bi) } } -static void print_raid5_conf (raid5_conf_t *conf); +static void print_raid5_conf (struct r5conf *conf); static int stripe_operations_active(struct stripe_head *sh) { @@ -192,7 +190,7 @@ static int stripe_operations_active(struct stripe_head *sh) test_bit(STRIPE_COMPUTE_RUN, &sh->state); } -static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh) +static void __release_stripe(struct r5conf *conf, struct stripe_head *sh) { if (atomic_dec_and_test(&sh->count)) { BUG_ON(!list_empty(&sh->lru)); @@ -228,7 +226,7 @@ static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh) static void release_stripe(struct stripe_head *sh) { - raid5_conf_t *conf = sh->raid_conf; + struct r5conf *conf = sh->raid_conf; unsigned long flags; spin_lock_irqsave(&conf->device_lock, flags); @@ -244,25 +242,23 @@ static inline void remove_hash(struct stripe_head *sh) hlist_del_init(&sh->hash); } -static inline void insert_hash(raid5_conf_t *conf, struct stripe_head *sh) +static inline void insert_hash(struct r5conf *conf, struct stripe_head *sh) { struct hlist_head *hp = stripe_hash(conf, sh->sector); pr_debug("insert_hash(), stripe %llu\n", (unsigned long long)sh->sector); - CHECK_DEVLOCK(); hlist_add_head(&sh->hash, hp); } /* find an idle stripe, make sure it is unhashed, and return it. */ -static struct stripe_head *get_free_stripe(raid5_conf_t *conf) +static struct stripe_head *get_free_stripe(struct r5conf *conf) { struct stripe_head *sh = NULL; struct list_head *first; - CHECK_DEVLOCK(); if (list_empty(&conf->inactive_list)) goto out; first = conf->inactive_list.next; @@ -306,19 +302,18 @@ static int grow_buffers(struct stripe_head *sh) } static void raid5_build_block(struct stripe_head *sh, int i, int previous); -static void stripe_set_idx(sector_t stripe, raid5_conf_t *conf, int previous, +static void stripe_set_idx(sector_t stripe, struct r5conf *conf, int previous, struct stripe_head *sh); static void init_stripe(struct stripe_head *sh, sector_t sector, int previous) { - raid5_conf_t *conf = sh->raid_conf; + struct r5conf *conf = sh->raid_conf; int i; BUG_ON(atomic_read(&sh->count) != 0); BUG_ON(test_bit(STRIPE_HANDLE, &sh->state)); BUG_ON(stripe_operations_active(sh)); - CHECK_DEVLOCK(); pr_debug("init_stripe called, stripe %llu\n", (unsigned long long)sh->sector); @@ -348,13 +343,12 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int previous) insert_hash(conf, sh); } -static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, +static struct stripe_head *__find_stripe(struct r5conf *conf, sector_t sector, short generation) { struct stripe_head *sh; struct hlist_node *hn; - CHECK_DEVLOCK(); pr_debug("__find_stripe, sector %llu\n", (unsigned long long)sector); hlist_for_each_entry(sh, hn, stripe_hash(conf, sector), hash) if (sh->sector == sector && sh->generation == generation) @@ -376,7 +370,7 @@ static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, * of the two sections, and some non-in_sync devices may * be insync in the section most affected by failed devices. */ -static int has_failed(raid5_conf_t *conf) +static int has_failed(struct r5conf *conf) { int degraded; int i; @@ -386,7 +380,7 @@ static int has_failed(raid5_conf_t *conf) rcu_read_lock(); degraded = 0; for (i = 0; i < conf->previous_raid_disks; i++) { - mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev); + struct md_rdev *rdev = rcu_dereference(conf->disks[i].rdev); if (!rdev || test_bit(Faulty, &rdev->flags)) degraded++; else if (test_bit(In_sync, &rdev->flags)) @@ -410,7 +404,7 @@ static int has_failed(raid5_conf_t *conf) rcu_read_lock(); degraded = 0; for (i = 0; i < conf->raid_disks; i++) { - mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev); + struct md_rdev *rdev = rcu_dereference(conf->disks[i].rdev); if (!rdev || test_bit(Faulty, &rdev->flags)) degraded++; else if (test_bit(In_sync, &rdev->flags)) @@ -431,7 +425,7 @@ static int has_failed(raid5_conf_t *conf) } static struct stripe_head * -get_active_stripe(raid5_conf_t *conf, sector_t sector, +get_active_stripe(struct r5conf *conf, sector_t sector, int previous, int noblock, int noquiesce) { struct stripe_head *sh; @@ -491,7 +485,7 @@ raid5_end_write_request(struct bio *bi, int error); static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) { - raid5_conf_t *conf = sh->raid_conf; + struct r5conf *conf = sh->raid_conf; int i, disks = sh->disks; might_sleep(); @@ -499,7 +493,7 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) for (i = disks; i--; ) { int rw; struct bio *bi; - mdk_rdev_t *rdev; + struct md_rdev *rdev; if (test_and_clear_bit(R5_Wantwrite, &sh->dev[i].flags)) { if (test_and_clear_bit(R5_WantFUA, &sh->dev[i].flags)) rw = WRITE_FUA; @@ -650,7 +644,7 @@ static void ops_complete_biofill(void *stripe_head_ref) { struct stripe_head *sh = stripe_head_ref; struct bio *return_bi = NULL; - raid5_conf_t *conf = sh->raid_conf; + struct r5conf *conf = sh->raid_conf; int i; pr_debug("%s: stripe %llu\n", __func__, @@ -695,7 +689,7 @@ static void ops_complete_biofill(void *stripe_head_ref) static void ops_run_biofill(struct stripe_head *sh) { struct dma_async_tx_descriptor *tx = NULL; - raid5_conf_t *conf = sh->raid_conf; + struct r5conf *conf = sh->raid_conf; struct async_submit_ctl submit; int i; @@ -1246,7 +1240,7 @@ static void __raid_run_ops(struct stripe_head *sh, unsigned long ops_request) { int overlap_clear = 0, i, disks = sh->disks; struct dma_async_tx_descriptor *tx = NULL; - raid5_conf_t *conf = sh->raid_conf; + struct r5conf *conf = sh->raid_conf; int level = conf->level; struct raid5_percpu *percpu; unsigned long cpu; @@ -1337,7 +1331,7 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) #define raid_run_ops __raid_run_ops #endif -static int grow_one_stripe(raid5_conf_t *conf) +static int grow_one_stripe(struct r5conf *conf) { struct stripe_head *sh; sh = kmem_cache_zalloc(conf->slab_cache, GFP_KERNEL); @@ -1362,7 +1356,7 @@ static int grow_one_stripe(raid5_conf_t *conf) return 1; } -static int grow_stripes(raid5_conf_t *conf, int num) +static int grow_stripes(struct r5conf *conf, int num) { struct kmem_cache *sc; int devs = max(conf->raid_disks, conf->previous_raid_disks); @@ -1411,7 +1405,7 @@ static size_t scribble_len(int num) return len; } -static int resize_stripes(raid5_conf_t *conf, int newsize) +static int resize_stripes(struct r5conf *conf, int newsize) { /* Make all the stripes able to hold 'newsize' devices. * New slots in each stripe get 'page' set to a new page. @@ -1556,7 +1550,7 @@ static int resize_stripes(raid5_conf_t *conf, int newsize) return err; } -static int drop_one_stripe(raid5_conf_t *conf) +static int drop_one_stripe(struct r5conf *conf) { struct stripe_head *sh; @@ -1572,7 +1566,7 @@ static int drop_one_stripe(raid5_conf_t *conf) return 1; } -static void shrink_stripes(raid5_conf_t *conf) +static void shrink_stripes(struct r5conf *conf) { while (drop_one_stripe(conf)) ; @@ -1585,11 +1579,11 @@ static void shrink_stripes(raid5_conf_t *conf) static void raid5_end_read_request(struct bio * bi, int error) { struct stripe_head *sh = bi->bi_private; - raid5_conf_t *conf = sh->raid_conf; + struct r5conf *conf = sh->raid_conf; int disks = sh->disks, i; int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags); char b[BDEVNAME_SIZE]; - mdk_rdev_t *rdev; + struct md_rdev *rdev; for (i=0 ; i<disks; i++) @@ -1672,7 +1666,7 @@ static void raid5_end_read_request(struct bio * bi, int error) static void raid5_end_write_request(struct bio *bi, int error) { struct stripe_head *sh = bi->bi_private; - raid5_conf_t *conf = sh->raid_conf; + struct r5conf *conf = sh->raid_conf; int disks = sh->disks, i; int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags); sector_t first_bad; @@ -1726,10 +1720,10 @@ static void raid5_build_block(struct stripe_head *sh, int i, int previous) dev->sector = compute_blocknr(sh, i, previous); } -static void error(mddev_t *mddev, mdk_rdev_t *rdev) +static void error(struct mddev *mddev, struct md_rdev *rdev) { char b[BDEVNAME_SIZE]; - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; pr_debug("raid456: error called\n"); if (test_and_clear_bit(In_sync, &rdev->flags)) { @@ -1758,7 +1752,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) * Input: a 'big' sector number, * Output: index of the data and parity disk, and the sector # in them. */ -static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, +static sector_t raid5_compute_sector(struct r5conf *conf, sector_t r_sector, int previous, int *dd_idx, struct stripe_head *sh) { @@ -1963,7 +1957,7 @@ static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector, static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous) { - raid5_conf_t *conf = sh->raid_conf; + struct r5conf *conf = sh->raid_conf; int raid_disks = sh->disks; int data_disks = raid_disks - conf->max_degraded; sector_t new_sector = sh->sector, check; @@ -2088,7 +2082,7 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s, int rcw, int expand) { int i, pd_idx = sh->pd_idx, disks = sh->disks; - raid5_conf_t *conf = sh->raid_conf; + struct r5conf *conf = sh->raid_conf; int level = conf->level; if (rcw) { @@ -2173,7 +2167,7 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s, static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, int forwrite) { struct bio **bip; - raid5_conf_t *conf = sh->raid_conf; + struct r5conf *conf = sh->raid_conf; int firstwrite=0; pr_debug("adding bi b#%llu to stripe s#%llu\n", @@ -2235,9 +2229,9 @@ static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, in return 0; } -static void end_reshape(raid5_conf_t *conf); +static void end_reshape(struct r5conf *conf); -static void stripe_set_idx(sector_t stripe, raid5_conf_t *conf, int previous, +static void stripe_set_idx(sector_t stripe, struct r5conf *conf, int previous, struct stripe_head *sh) { int sectors_per_chunk = @@ -2254,7 +2248,7 @@ static void stripe_set_idx(sector_t stripe, raid5_conf_t *conf, int previous, } static void -handle_failed_stripe(raid5_conf_t *conf, struct stripe_head *sh, +handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh, struct stripe_head_state *s, int disks, struct bio **return_bi) { @@ -2264,7 +2258,7 @@ handle_failed_stripe(raid5_conf_t *conf, struct stripe_head *sh, int bitmap_end = 0; if (test_bit(R5_ReadError, &sh->dev[i].flags)) { - mdk_rdev_t *rdev; + struct md_rdev *rdev; rcu_read_lock(); rdev = rcu_dereference(conf->disks[i].rdev); if (rdev && test_bit(In_sync, &rdev->flags)) @@ -2359,7 +2353,7 @@ handle_failed_stripe(raid5_conf_t *conf, struct stripe_head *sh, } static void -handle_failed_sync(raid5_conf_t *conf, struct stripe_head *sh, +handle_failed_sync(struct r5conf *conf, struct stripe_head *sh, struct stripe_head_state *s) { int abort = 0; @@ -2378,7 +2372,7 @@ handle_failed_sync(raid5_conf_t *conf, struct stripe_head *sh, * refcounting of rdevs is not needed */ for (i = 0; i < conf->raid_disks; i++) { - mdk_rdev_t *rdev = conf->disks[i].rdev; + struct md_rdev *rdev = conf->disks[i].rdev; if (!rdev || test_bit(Faulty, &rdev->flags) || test_bit(In_sync, &rdev->flags)) @@ -2508,7 +2502,7 @@ static void handle_stripe_fill(struct stripe_head *sh, * Note that if we 'wrote' to a failed drive, it will be UPTODATE, but * never LOCKED, so we don't need to test 'failed' directly. */ -static void handle_stripe_clean_event(raid5_conf_t *conf, +static void handle_stripe_clean_event(struct r5conf *conf, struct stripe_head *sh, int disks, struct bio **return_bi) { int i; @@ -2553,7 +2547,7 @@ static void handle_stripe_clean_event(raid5_conf_t *conf, md_wakeup_thread(conf->mddev->thread); } -static void handle_stripe_dirtying(raid5_conf_t *conf, +static void handle_stripe_dirtying(struct r5conf *conf, struct stripe_head *sh, struct stripe_head_state *s, int disks) @@ -2655,7 +2649,7 @@ static void handle_stripe_dirtying(raid5_conf_t *conf, schedule_reconstruction(sh, s, rcw == 0, 0); } -static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh, +static void handle_parity_checks5(struct r5conf *conf, struct stripe_head *sh, struct stripe_head_state *s, int disks) { struct r5dev *dev = NULL; @@ -2743,7 +2737,7 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh, } -static void handle_parity_checks6(raid5_conf_t *conf, struct stripe_head *sh, +static void handle_parity_checks6(struct r5conf *conf, struct stripe_head *sh, struct stripe_head_state *s, int disks) { @@ -2906,7 +2900,7 @@ static void handle_parity_checks6(raid5_conf_t *conf, struct stripe_head *sh, } } -static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh) +static void handle_stripe_expansion(struct r5conf *conf, struct stripe_head *sh) { int i; @@ -2985,7 +2979,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh) static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) { - raid5_conf_t *conf = sh->raid_conf; + struct r5conf *conf = sh->raid_conf; int disks = sh->disks; struct r5dev *dev; int i; @@ -3002,7 +2996,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) rcu_read_lock(); spin_lock_irq(&conf->device_lock); for (i=disks; i--; ) { - mdk_rdev_t *rdev; + struct md_rdev *rdev; sector_t first_bad; int bad_sectors; int is_bad = 0; @@ -3069,7 +3063,7 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) } } else if (test_bit(In_sync, &rdev->flags)) set_bit(R5_Insync, &dev->flags); - else { + else if (!test_bit(Faulty, &rdev->flags)) { /* in sync if before recovery_offset */ if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset) set_bit(R5_Insync, &dev->flags); @@ -3109,14 +3103,14 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s) static void handle_stripe(struct stripe_head *sh) { struct stripe_head_state s; - raid5_conf_t *conf = sh->raid_conf; + struct r5conf *conf = sh->raid_conf; int i; int prexor; int disks = sh->disks; struct r5dev *pdev, *qdev; clear_bit(STRIPE_HANDLE, &sh->state); - if (test_and_set_bit(STRIPE_ACTIVE, &sh->state)) { + if (test_and_set_bit_lock(STRIPE_ACTIVE, &sh->state)) { /* already being handled, ensure it gets handled * again when current action finishes */ set_bit(STRIPE_HANDLE, &sh->state); @@ -3165,10 +3159,14 @@ static void handle_stripe(struct stripe_head *sh) /* check if the array has lost more than max_degraded devices and, * if so, some requests might need to be failed. */ - if (s.failed > conf->max_degraded && s.to_read+s.to_write+s.written) - handle_failed_stripe(conf, sh, &s, disks, &s.return_bi); - if (s.failed > conf->max_degraded && s.syncing) - handle_failed_sync(conf, sh, &s); + if (s.failed > conf->max_degraded) { + sh->check_state = 0; + sh->reconstruct_state = 0; + if (s.to_read+s.to_write+s.written) + handle_failed_stripe(conf, sh, &s, disks, &s.return_bi); + if (s.syncing) + handle_failed_sync(conf, sh, &s); + } /* * might be able to return some write requests if the parity blocks @@ -3341,7 +3339,7 @@ finish: if (s.handle_bad_blocks) for (i = disks; i--; ) { - mdk_rdev_t *rdev; + struct md_rdev *rdev; struct r5dev *dev = &sh->dev[i]; if (test_and_clear_bit(R5_WriteError, &dev->flags)) { /* We own a safe reference to the rdev */ @@ -3377,10 +3375,10 @@ finish: return_io(s.return_bi); - clear_bit(STRIPE_ACTIVE, &sh->state); + clear_bit_unlock(STRIPE_ACTIVE, &sh->state); } -static void raid5_activate_delayed(raid5_conf_t *conf) +static void raid5_activate_delayed(struct r5conf *conf) { if (atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD) { while (!list_empty(&conf->delayed_list)) { @@ -3396,7 +3394,7 @@ static void raid5_activate_delayed(raid5_conf_t *conf) } } -static void activate_bit_delay(raid5_conf_t *conf) +static void activate_bit_delay(struct r5conf *conf) { /* device_lock is held */ struct list_head head; @@ -3410,9 +3408,9 @@ static void activate_bit_delay(raid5_conf_t *conf) } } -int md_raid5_congested(mddev_t *mddev, int bits) +int md_raid5_congested(struct mddev *mddev, int bits) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; /* No difference between reads and writes. Just check * how busy the stripe_cache is @@ -3431,7 +3429,7 @@ EXPORT_SYMBOL_GPL(md_raid5_congested); static int raid5_congested(void *data, int bits) { - mddev_t *mddev = data; + struct mddev *mddev = data; return mddev_congested(mddev, bits) || md_raid5_congested(mddev, bits); @@ -3444,7 +3442,7 @@ static int raid5_mergeable_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct bio_vec *biovec) { - mddev_t *mddev = q->queuedata; + struct mddev *mddev = q->queuedata; sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); int max; unsigned int chunk_sectors = mddev->chunk_sectors; @@ -3464,7 +3462,7 @@ static int raid5_mergeable_bvec(struct request_queue *q, } -static int in_chunk_boundary(mddev_t *mddev, struct bio *bio) +static int in_chunk_boundary(struct mddev *mddev, struct bio *bio) { sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev); unsigned int chunk_sectors = mddev->chunk_sectors; @@ -3480,7 +3478,7 @@ static int in_chunk_boundary(mddev_t *mddev, struct bio *bio) * add bio to the retry LIFO ( in O(1) ... we are in interrupt ) * later sampled by raid5d. */ -static void add_bio_to_retry(struct bio *bi,raid5_conf_t *conf) +static void add_bio_to_retry(struct bio *bi,struct r5conf *conf) { unsigned long flags; @@ -3494,7 +3492,7 @@ static void add_bio_to_retry(struct bio *bi,raid5_conf_t *conf) } -static struct bio *remove_bio_from_retry(raid5_conf_t *conf) +static struct bio *remove_bio_from_retry(struct r5conf *conf) { struct bio *bi; @@ -3527,10 +3525,10 @@ static struct bio *remove_bio_from_retry(raid5_conf_t *conf) static void raid5_align_endio(struct bio *bi, int error) { struct bio* raid_bi = bi->bi_private; - mddev_t *mddev; - raid5_conf_t *conf; + struct mddev *mddev; + struct r5conf *conf; int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags); - mdk_rdev_t *rdev; + struct md_rdev *rdev; bio_put(bi); @@ -3574,12 +3572,12 @@ static int bio_fits_rdev(struct bio *bi) } -static int chunk_aligned_read(mddev_t *mddev, struct bio * raid_bio) +static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; int dd_idx; struct bio* align_bi; - mdk_rdev_t *rdev; + struct md_rdev *rdev; if (!in_chunk_boundary(mddev, raid_bio)) { pr_debug("chunk_aligned_read : non aligned\n"); @@ -3652,7 +3650,7 @@ static int chunk_aligned_read(mddev_t *mddev, struct bio * raid_bio) * head of the hold_list has changed, i.e. the head was promoted to the * handle_list. */ -static struct stripe_head *__get_priority_stripe(raid5_conf_t *conf) +static struct stripe_head *__get_priority_stripe(struct r5conf *conf) { struct stripe_head *sh; @@ -3695,9 +3693,9 @@ static struct stripe_head *__get_priority_stripe(raid5_conf_t *conf) return sh; } -static int make_request(mddev_t *mddev, struct bio * bi) +static void make_request(struct mddev *mddev, struct bio * bi) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; int dd_idx; sector_t new_sector; sector_t logical_sector, last_sector; @@ -3708,7 +3706,7 @@ static int make_request(mddev_t *mddev, struct bio * bi) if (unlikely(bi->bi_rw & REQ_FLUSH)) { md_flush_request(mddev, bi); - return 0; + return; } md_write_start(mddev, bi); @@ -3716,7 +3714,7 @@ static int make_request(mddev_t *mddev, struct bio * bi) if (rw == READ && mddev->reshape_position == MaxSector && chunk_aligned_read(mddev,bi)) - return 0; + return; logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1); last_sector = bi->bi_sector + (bi->bi_size>>9); @@ -3851,13 +3849,11 @@ static int make_request(mddev_t *mddev, struct bio * bi) bio_endio(bi, 0); } - - return 0; } -static sector_t raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks); +static sector_t raid5_size(struct mddev *mddev, sector_t sectors, int raid_disks); -static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped) +static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *skipped) { /* reshaping is quite different to recovery/resync so it is * handled quite separately ... here. @@ -3868,7 +3864,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped * As the reads complete, handle_stripe will copy the data * into the destination stripe and release that stripe. */ - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; struct stripe_head *sh; sector_t first_sector, last_sector; int raid_disks = conf->previous_raid_disks; @@ -4075,9 +4071,9 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped } /* FIXME go_faster isn't used */ -static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster) +static inline sector_t sync_request(struct mddev *mddev, sector_t sector_nr, int *skipped, int go_faster) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; struct stripe_head *sh; sector_t max_sector = mddev->dev_sectors; sector_t sync_blocks; @@ -4162,7 +4158,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski return STRIPE_SECTORS; } -static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio) +static int retry_aligned_read(struct r5conf *conf, struct bio *raid_bio) { /* We may not be able to submit a whole bio at once as there * may not be enough stripe_heads available. @@ -4234,10 +4230,10 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio) * During the scan, completed stripes are saved for us by the interrupt * handler, so that they will not have to wait for our next wakeup. */ -static void raid5d(mddev_t *mddev) +static void raid5d(struct mddev *mddev) { struct stripe_head *sh; - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; int handled; struct blk_plug plug; @@ -4301,9 +4297,9 @@ static void raid5d(mddev_t *mddev) } static ssize_t -raid5_show_stripe_cache_size(mddev_t *mddev, char *page) +raid5_show_stripe_cache_size(struct mddev *mddev, char *page) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; if (conf) return sprintf(page, "%d\n", conf->max_nr_stripes); else @@ -4311,9 +4307,9 @@ raid5_show_stripe_cache_size(mddev_t *mddev, char *page) } int -raid5_set_cache_size(mddev_t *mddev, int size) +raid5_set_cache_size(struct mddev *mddev, int size) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; int err; if (size <= 16 || size > 32768) @@ -4337,9 +4333,9 @@ raid5_set_cache_size(mddev_t *mddev, int size) EXPORT_SYMBOL(raid5_set_cache_size); static ssize_t -raid5_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len) +raid5_store_stripe_cache_size(struct mddev *mddev, const char *page, size_t len) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; unsigned long new; int err; @@ -4362,9 +4358,9 @@ raid5_stripecache_size = __ATTR(stripe_cache_size, S_IRUGO | S_IWUSR, raid5_store_stripe_cache_size); static ssize_t -raid5_show_preread_threshold(mddev_t *mddev, char *page) +raid5_show_preread_threshold(struct mddev *mddev, char *page) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; if (conf) return sprintf(page, "%d\n", conf->bypass_threshold); else @@ -4372,9 +4368,9 @@ raid5_show_preread_threshold(mddev_t *mddev, char *page) } static ssize_t -raid5_store_preread_threshold(mddev_t *mddev, const char *page, size_t len) +raid5_store_preread_threshold(struct mddev *mddev, const char *page, size_t len) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; unsigned long new; if (len >= PAGE_SIZE) return -EINVAL; @@ -4396,9 +4392,9 @@ raid5_preread_bypass_threshold = __ATTR(preread_bypass_threshold, raid5_store_preread_threshold); static ssize_t -stripe_cache_active_show(mddev_t *mddev, char *page) +stripe_cache_active_show(struct mddev *mddev, char *page) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; if (conf) return sprintf(page, "%d\n", atomic_read(&conf->active_stripes)); else @@ -4420,9 +4416,9 @@ static struct attribute_group raid5_attrs_group = { }; static sector_t -raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks) +raid5_size(struct mddev *mddev, sector_t sectors, int raid_disks) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; if (!sectors) sectors = mddev->dev_sectors; @@ -4435,7 +4431,7 @@ raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks) return sectors * (raid_disks - conf->max_degraded); } -static void raid5_free_percpu(raid5_conf_t *conf) +static void raid5_free_percpu(struct r5conf *conf) { struct raid5_percpu *percpu; unsigned long cpu; @@ -4457,7 +4453,7 @@ static void raid5_free_percpu(raid5_conf_t *conf) free_percpu(conf->percpu); } -static void free_conf(raid5_conf_t *conf) +static void free_conf(struct r5conf *conf) { shrink_stripes(conf); raid5_free_percpu(conf); @@ -4470,7 +4466,7 @@ static void free_conf(raid5_conf_t *conf) static int raid456_cpu_notify(struct notifier_block *nfb, unsigned long action, void *hcpu) { - raid5_conf_t *conf = container_of(nfb, raid5_conf_t, cpu_notify); + struct r5conf *conf = container_of(nfb, struct r5conf, cpu_notify); long cpu = (long)hcpu; struct raid5_percpu *percpu = per_cpu_ptr(conf->percpu, cpu); @@ -4505,7 +4501,7 @@ static int raid456_cpu_notify(struct notifier_block *nfb, unsigned long action, } #endif -static int raid5_alloc_percpu(raid5_conf_t *conf) +static int raid5_alloc_percpu(struct r5conf *conf) { unsigned long cpu; struct page *spare_page; @@ -4547,11 +4543,11 @@ static int raid5_alloc_percpu(raid5_conf_t *conf) return err; } -static raid5_conf_t *setup_conf(mddev_t *mddev) +static struct r5conf *setup_conf(struct mddev *mddev) { - raid5_conf_t *conf; + struct r5conf *conf; int raid_disk, memory, max_disks; - mdk_rdev_t *rdev; + struct md_rdev *rdev; struct disk_info *disk; if (mddev->new_level != 5 @@ -4583,7 +4579,7 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) return ERR_PTR(-EINVAL); } - conf = kzalloc(sizeof(raid5_conf_t), GFP_KERNEL); + conf = kzalloc(sizeof(struct r5conf), GFP_KERNEL); if (conf == NULL) goto abort; spin_lock_init(&conf->device_lock); @@ -4598,6 +4594,7 @@ static raid5_conf_t *setup_conf(mddev_t *mddev) atomic_set(&conf->preread_active_stripes, 0); atomic_set(&conf->active_aligned_reads, 0); conf->bypass_threshold = BYPASS_THRESHOLD; + conf->recovery_disabled = mddev->recovery_disabled - 1; conf->raid_disks = mddev->raid_disks; if (mddev->reshape_position == MaxSector) @@ -4712,12 +4709,12 @@ static int only_parity(int raid_disk, int algo, int raid_disks, int max_degraded return 0; } -static int run(mddev_t *mddev) +static int run(struct mddev *mddev) { - raid5_conf_t *conf; + struct r5conf *conf; int working_disks = 0; int dirty_parity_disks = 0; - mdk_rdev_t *rdev; + struct md_rdev *rdev; sector_t reshape_offset = 0; if (mddev->recovery_cp != MaxSector) @@ -4942,18 +4939,16 @@ static int run(mddev_t *mddev) return 0; abort: md_unregister_thread(&mddev->thread); - if (conf) { - print_raid5_conf(conf); - free_conf(conf); - } + print_raid5_conf(conf); + free_conf(conf); mddev->private = NULL; printk(KERN_ALERT "md/raid:%s: failed to run raid set.\n", mdname(mddev)); return -EIO; } -static int stop(mddev_t *mddev) +static int stop(struct mddev *mddev) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; md_unregister_thread(&mddev->thread); if (mddev->queue) @@ -4964,44 +4959,9 @@ static int stop(mddev_t *mddev) return 0; } -#ifdef DEBUG -static void print_sh(struct seq_file *seq, struct stripe_head *sh) -{ - int i; - - seq_printf(seq, "sh %llu, pd_idx %d, state %ld.\n", - (unsigned long long)sh->sector, sh->pd_idx, sh->state); - seq_printf(seq, "sh %llu, count %d.\n", - (unsigned long long)sh->sector, atomic_read(&sh->count)); - seq_printf(seq, "sh %llu, ", (unsigned long long)sh->sector); - for (i = 0; i < sh->disks; i++) { - seq_printf(seq, "(cache%d: %p %ld) ", - i, sh->dev[i].page, sh->dev[i].flags); - } - seq_printf(seq, "\n"); -} - -static void printall(struct seq_file *seq, raid5_conf_t *conf) -{ - struct stripe_head *sh; - struct hlist_node *hn; - int i; - - spin_lock_irq(&conf->device_lock); - for (i = 0; i < NR_HASH; i++) { - hlist_for_each_entry(sh, hn, &conf->stripe_hashtbl[i], hash) { - if (sh->raid_conf != conf) - continue; - print_sh(seq, sh); - } - } - spin_unlock_irq(&conf->device_lock); -} -#endif - -static void status(struct seq_file *seq, mddev_t *mddev) +static void status(struct seq_file *seq, struct mddev *mddev) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; int i; seq_printf(seq, " level %d, %dk chunk, algorithm %d", mddev->level, @@ -5012,13 +4972,9 @@ static void status(struct seq_file *seq, mddev_t *mddev) conf->disks[i].rdev && test_bit(In_sync, &conf->disks[i].rdev->flags) ? "U" : "_"); seq_printf (seq, "]"); -#ifdef DEBUG - seq_printf (seq, "\n"); - printall(seq, conf); -#endif } -static void print_raid5_conf (raid5_conf_t *conf) +static void print_raid5_conf (struct r5conf *conf) { int i; struct disk_info *tmp; @@ -5042,10 +4998,10 @@ static void print_raid5_conf (raid5_conf_t *conf) } } -static int raid5_spare_active(mddev_t *mddev) +static int raid5_spare_active(struct mddev *mddev) { int i; - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; struct disk_info *tmp; int count = 0; unsigned long flags; @@ -5067,11 +5023,11 @@ static int raid5_spare_active(mddev_t *mddev) return count; } -static int raid5_remove_disk(mddev_t *mddev, int number) +static int raid5_remove_disk(struct mddev *mddev, int number) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; int err = 0; - mdk_rdev_t *rdev; + struct md_rdev *rdev; struct disk_info *p = conf->disks + number; print_raid5_conf(conf); @@ -5110,9 +5066,9 @@ abort: return err; } -static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) +static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; int err = -EEXIST; int disk; struct disk_info *p; @@ -5153,7 +5109,7 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) return err; } -static int raid5_resize(mddev_t *mddev, sector_t sectors) +static int raid5_resize(struct mddev *mddev, sector_t sectors) { /* no resync is happening, and there is enough space * on all devices, so we can resize. @@ -5180,7 +5136,7 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors) return 0; } -static int check_stripe_cache(mddev_t *mddev) +static int check_stripe_cache(struct mddev *mddev) { /* Can only proceed if there are plenty of stripe_heads. * We need a minimum of one full stripe,, and for sensible progress @@ -5190,7 +5146,7 @@ static int check_stripe_cache(mddev_t *mddev) * If the chunk size is greater, user-space should request more * stripe_heads first. */ - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; if (((mddev->chunk_sectors << 9) / STRIPE_SIZE) * 4 > conf->max_nr_stripes || ((mddev->new_chunk_sectors << 9) / STRIPE_SIZE) * 4 @@ -5204,9 +5160,9 @@ static int check_stripe_cache(mddev_t *mddev) return 1; } -static int check_reshape(mddev_t *mddev) +static int check_reshape(struct mddev *mddev) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; if (mddev->delta_disks == 0 && mddev->new_layout == mddev->layout && @@ -5236,10 +5192,10 @@ static int check_reshape(mddev_t *mddev) return resize_stripes(conf, conf->raid_disks + mddev->delta_disks); } -static int raid5_start_reshape(mddev_t *mddev) +static int raid5_start_reshape(struct mddev *mddev) { - raid5_conf_t *conf = mddev->private; - mdk_rdev_t *rdev; + struct r5conf *conf = mddev->private; + struct md_rdev *rdev; int spares = 0; unsigned long flags; @@ -5353,7 +5309,7 @@ static int raid5_start_reshape(mddev_t *mddev) /* This is called from the reshape thread and should make any * changes needed in 'conf' */ -static void end_reshape(raid5_conf_t *conf) +static void end_reshape(struct r5conf *conf) { if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) { @@ -5380,9 +5336,9 @@ static void end_reshape(raid5_conf_t *conf) /* This is called from the raid5d thread with mddev_lock held. * It makes config changes to the device. */ -static void raid5_finish_reshape(mddev_t *mddev) +static void raid5_finish_reshape(struct mddev *mddev) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) { @@ -5401,7 +5357,7 @@ static void raid5_finish_reshape(mddev_t *mddev) for (d = conf->raid_disks ; d < conf->raid_disks - mddev->delta_disks; d++) { - mdk_rdev_t *rdev = conf->disks[d].rdev; + struct md_rdev *rdev = conf->disks[d].rdev; if (rdev && raid5_remove_disk(mddev, d) == 0) { sysfs_unlink_rdev(mddev, rdev); rdev->raid_disk = -1; @@ -5415,9 +5371,9 @@ static void raid5_finish_reshape(mddev_t *mddev) } } -static void raid5_quiesce(mddev_t *mddev, int state) +static void raid5_quiesce(struct mddev *mddev, int state) { - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; switch(state) { case 2: /* resume for a suspend */ @@ -5451,20 +5407,20 @@ static void raid5_quiesce(mddev_t *mddev, int state) } -static void *raid45_takeover_raid0(mddev_t *mddev, int level) +static void *raid45_takeover_raid0(struct mddev *mddev, int level) { - struct raid0_private_data *raid0_priv = mddev->private; + struct r0conf *raid0_conf = mddev->private; sector_t sectors; /* for raid0 takeover only one zone is supported */ - if (raid0_priv->nr_strip_zones > 1) { + if (raid0_conf->nr_strip_zones > 1) { printk(KERN_ERR "md/raid:%s: cannot takeover raid0 with more than one zone.\n", mdname(mddev)); return ERR_PTR(-EINVAL); } - sectors = raid0_priv->strip_zone[0].zone_end; - sector_div(sectors, raid0_priv->strip_zone[0].nb_dev); + sectors = raid0_conf->strip_zone[0].zone_end; + sector_div(sectors, raid0_conf->strip_zone[0].nb_dev); mddev->dev_sectors = sectors; mddev->new_level = level; mddev->new_layout = ALGORITHM_PARITY_N; @@ -5478,7 +5434,7 @@ static void *raid45_takeover_raid0(mddev_t *mddev, int level) } -static void *raid5_takeover_raid1(mddev_t *mddev) +static void *raid5_takeover_raid1(struct mddev *mddev) { int chunksect; @@ -5505,7 +5461,7 @@ static void *raid5_takeover_raid1(mddev_t *mddev) return setup_conf(mddev); } -static void *raid5_takeover_raid6(mddev_t *mddev) +static void *raid5_takeover_raid6(struct mddev *mddev) { int new_layout; @@ -5539,14 +5495,14 @@ static void *raid5_takeover_raid6(mddev_t *mddev) } -static int raid5_check_reshape(mddev_t *mddev) +static int raid5_check_reshape(struct mddev *mddev) { /* For a 2-drive array, the layout and chunk size can be changed * immediately as not restriping is needed. * For larger arrays we record the new value - after validation * to be used by a reshape pass. */ - raid5_conf_t *conf = mddev->private; + struct r5conf *conf = mddev->private; int new_chunk = mddev->new_chunk_sectors; if (mddev->new_layout >= 0 && !algorithm_valid_raid5(mddev->new_layout)) @@ -5579,7 +5535,7 @@ static int raid5_check_reshape(mddev_t *mddev) return check_reshape(mddev); } -static int raid6_check_reshape(mddev_t *mddev) +static int raid6_check_reshape(struct mddev *mddev) { int new_chunk = mddev->new_chunk_sectors; @@ -5599,7 +5555,7 @@ static int raid6_check_reshape(mddev_t *mddev) return check_reshape(mddev); } -static void *raid5_takeover(mddev_t *mddev) +static void *raid5_takeover(struct mddev *mddev) { /* raid5 can take over: * raid0 - if there is only one strip zone - make it a raid4 layout @@ -5622,7 +5578,7 @@ static void *raid5_takeover(mddev_t *mddev) return ERR_PTR(-EINVAL); } -static void *raid4_takeover(mddev_t *mddev) +static void *raid4_takeover(struct mddev *mddev) { /* raid4 can take over: * raid0 - if there is only one strip zone @@ -5639,9 +5595,9 @@ static void *raid4_takeover(mddev_t *mddev) return ERR_PTR(-EINVAL); } -static struct mdk_personality raid5_personality; +static struct md_personality raid5_personality; -static void *raid6_takeover(mddev_t *mddev) +static void *raid6_takeover(struct mddev *mddev) { /* Currently can only take over a raid5. We map the * personality to an equivalent raid6 personality @@ -5688,7 +5644,7 @@ static void *raid6_takeover(mddev_t *mddev) } -static struct mdk_personality raid6_personality = +static struct md_personality raid6_personality = { .name = "raid6", .level = 6, @@ -5710,7 +5666,7 @@ static struct mdk_personality raid6_personality = .quiesce = raid5_quiesce, .takeover = raid6_takeover, }; -static struct mdk_personality raid5_personality = +static struct md_personality raid5_personality = { .name = "raid5", .level = 5, @@ -5733,7 +5689,7 @@ static struct mdk_personality raid5_personality = .takeover = raid5_takeover, }; -static struct mdk_personality raid4_personality = +static struct md_personality raid4_personality = { .name = "raid4", .level = 4, |