// SPDX-License-Identifier: GPL-2.0-or-later/* * raid10.c : Multiple Devices driver for Linux * * Copyright (C) 2000-2004 Neil Brown * * RAID-10 support for md. * * Base on code in raid1.c. See raid1.c for further copyright information. */ #include <linux/slab.h>#include <linux/delay.h>#include <linux/blkdev.h>#include <linux/module.h>#include <linux/seq_file.h>#include <linux/ratelimit.h>#include <linux/kthread.h>#include <linux/raid/md_p.h>#include <trace/events/block.h>#include "md.h" #define RAID_1_10_NAME "raid10"#include "raid10.h"#include "raid0.h"#include "md-bitmap.h"#include "md-cluster.h" /* * RAID10 provides a combination of RAID0 and RAID1 functionality. * The layout of data is defined by * chunk_size * raid_disks * near_copies (stored in low byte of layout) * far_copies (stored in second byte of layout) * far_offset (stored in bit 16 of layout ) * use_far_sets (stored in bit 17 of layout ) * use_far_sets_bugfixed (stored in bit 18 of layout ) * * The data to be stored is divided into chunks using chunksize. Each device * is divided into far_copies sections. In each section, chunks are laid out * in a style similar to raid0, but near_copies copies of each chunk is stored * (each on a different drive). The starting device for each section is offset * near_copies from the starting device of the previous section. Thus there * are (near_copies * far_copies) of each chunk, and each is on a different * drive. near_copies and far_copies must be at least one, and their product * is at most raid_disks. * * If far_offset is true, then the far_copies are handled a bit differently. * The copies are still in different stripes, but instead of being very far * apart on disk, there are adjacent stripes. * * The far and offset algorithms are handled slightly differently if * 'use_far_sets' is true. In this case, the array's devices are grouped into * sets that are (near_copies * far_copies) in size. The far copied stripes * are still shifted by 'near_copies' devices, but this shifting stays confined * to the set rather than the entire array. This is done to improve the number * of device combinations that can fail without causing the array to fail. * Example 'far' algorithm w/o 'use_far_sets' (each letter represents a chunk * on a device): * A B C D A B C D E * ... ... * D A B C E A B C D * Example 'far' algorithm w/ 'use_far_sets' enabled (sets illustrated w/ []'s): * [A B] [C D] [A B] [C D E] * |...| |...| |...| | ... | * [B A] [D C] [B A] [E C D] */ static void allow_barrier(struct r10conf *conf);static void lower_barrier(struct r10conf *conf);static int _enough(struct r10conf *conf, int previous, int ignore);static int enough(struct r10conf *conf, int ignore);static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *skipped);static void reshape_request_write(struct mddev *mddev, struct r10bio *r10_bio);static void end_reshape_write(struct bio *bio);static void end_reshape(struct r10conf *conf); #include "raid1-10.c" #define NULL_CMD#define cmd_before(conf, cmd) \ do { \ write_sequnlock_irq(&(conf)->resync_lock); \ cmd; \ } while (0)#define cmd_after(conf) write_seqlock_irq(&(conf)->resync_lock) #define wait_event_barrier_cmd(conf, cond, cmd) \ wait_event_cmd((conf)->wait_barrier, cond, cmd_before(conf, cmd), \ cmd_after(conf)) #define wait_event_barrier(conf, cond) \ wait_event_barrier_cmd(conf, cond, NULL_CMD) /* * for resync bio, r10bio pointer can be retrieved from the per-bio * 'struct resync_pages'. */static inline struct r10bio *get_resync_r10bio(struct bio *bio){ return get_resync_pages(bio)->raid_bio;} static inline int calc_r10bio_size(unsigned int raid_disks){ return offsetof(struct r10bio, devs[raid_disks]);} static mempool_t *create_r10bio_pool(unsigned int raid_disks){ int size = calc_r10bio_size(raid_disks); return mempool_create_kmalloc_pool(NR_RAID_BIOS, size);} static struct r10bio *alloc_r10bio(unsigned int raid_disks, gfp_t gfp_flags){ int size = calc_r10bio_size(raid_disks); /* allocate a r10bio sized for current geometry */ return kzalloc(size, gfp_flags);} #define RESYNC_SECTORS (RESYNC_BLOCK_SIZE >> 9)/* amount of memory to reserve for resync requests */#define RESYNC_WINDOW (1024*1024)/* maximum number of concurrent requests, memory permitting */#define RESYNC_DEPTH (32*1024*1024/RESYNC_BLOCK_SIZE)#define CLUSTER_RESYNC_WINDOW (32 * RESYNC_WINDOW)#define CLUSTER_RESYNC_WINDOW_SECTORS (CLUSTER_RESYNC_WINDOW >> 9) /* * When performing a resync, we need to read and compare, so * we need as many pages are there are copies. * When performing a recovery, we need 2 bios, one for read, * one for write (we recover only one drive per r10buf) * */static void * r10buf_pool_alloc(gfp_t gfp_flags, void *data){ struct r10conf *conf = data; struct r10bio *r10_bio; struct bio *bio; int j; int nalloc, nalloc_rp; struct resync_pages *rps; r10_bio = alloc_r10bio(conf->geo.raid_disks, gfp_flags); if (!r10_bio) return NULL; if (test_bit(MD_RECOVERY_SYNC, &conf->mddev->recovery) || test_bit(MD_RECOVERY_RESHAPE, &conf->mddev->recovery)) nalloc = conf->copies; /* resync */ else nalloc = 2; /* recovery */ /* allocate once for all bios */ if (!conf->have_replacement) nalloc_rp = nalloc; else nalloc_rp = nalloc * 2; rps = kmalloc_objs(struct resync_pages, nalloc_rp, gfp_flags); if (!rps) goto out_free_r10bio; /* * Allocate bios. */ for (j = nalloc ; j-- ; ) { bio = bio_kmalloc(RESYNC_PAGES, gfp_flags); if (!bio) goto out_free_bio; bio_init_inline(bio, NULL, RESYNC_PAGES, 0); r10_bio->devs[j].bio = bio; if (!conf->have_replacement) continue; bio = bio_kmalloc(RESYNC_PAGES, gfp_flags); if (!bio) goto out_free_bio; bio_init_inline(bio, NULL, RESYNC_PAGES, 0); r10_bio->devs[j].repl_bio = bio; } /* * Allocate RESYNC_PAGES data pages and attach them * where needed. */ for (j = 0; j < nalloc; j++) { struct bio *rbio = r10_bio->devs[j].repl_bio; struct resync_pages *rp, *rp_repl; rp = &rps[j]; if (rbio) rp_repl = &rps[nalloc + j]; bio = r10_bio->devs[j].bio; if (!j || test_bit(MD_RECOVERY_SYNC, &conf->mddev->recovery)) { if (resync_alloc_pages(rp, gfp_flags)) goto out_free_pages; } else { memcpy(rp, &rps[0], sizeof(*rp)); resync_get_all_pages(rp); } rp->raid_bio = r10_bio; bio->bi_private = rp; if (rbio) { memcpy(rp_repl, rp, sizeof(*rp)); rbio->bi_private = rp_repl; } } return r10_bio; out_free_pages: while (--j >= 0) resync_free_pages(&rps[j]); j = 0;out_free_bio: for ( ; j < nalloc; j++) { if (r10_bio->devs[j].bio) bio_uninit(r10_bio->devs[j].bio); kfree(r10_bio->devs[j].bio); if (r10_bio->devs[j].repl_bio) bio_uninit(r10_bio->devs[j].repl_bio); kfree(r10_bio->devs[j].repl_bio); } kfree(rps);out_free_r10bio: rbio_pool_free(r10_bio, conf); return NULL;} static void r10buf_pool_free(void *__r10_bio, void *data){ struct r10conf *conf = data; struct r10bio *r10bio = __r10_bio; int j; struct resync_pages *rp = NULL; for (j = conf->copies; j--; ) { struct bio *bio = r10bio->devs[j].bio; if (bio) { rp = get_resync_pages(bio); resync_free_pages(rp); bio_uninit(bio); kfree(bio); } bio = r10bio->devs[j].repl_bio; if (bio) { bio_uninit(bio); kfree(bio); } } /* resync pages array stored in the 1st bio's .bi_private */ kfree(rp); rbio_pool_free(r10bio, conf);} static void put_all_bios(struct r10conf *conf, struct r10bio *r10_bio){ int i; for (i = 0; i < conf->geo.raid_disks; i++) { struct bio **bio = & r10_bio->devs[i].bio; if (!BIO_SPECIAL(*bio)) bio_put(*bio); *bio = NULL; bio = &r10_bio->devs[i].repl_bio; if (r10_bio->read_slot < 0 && !BIO_SPECIAL(*bio)) bio_put(*bio); *bio = NULL; }} static void free_r10bio(struct r10bio *r10_bio){ struct r10conf *conf = r10_bio->mddev->private; put_all_bios(conf, r10_bio); mempool_free(r10_bio, conf->r10bio_pool);} static void put_buf(struct r10bio *r10_bio){ struct r10conf *conf = r10_bio->mddev->private; mempool_free(r10_bio, &conf->r10buf_pool); lower_barrier(conf);} static void wake_up_barrier(struct r10conf *conf){ if (wq_has_sleeper(&conf->wait_barrier)) wake_up(&conf->wait_barrier);} static void reschedule_retry(struct r10bio *r10_bio){ unsigned long flags; struct mddev *mddev = r10_bio->mddev; struct r10conf *conf = mddev->private; spin_lock_irqsave(&conf->device_lock, flags); list_add(&r10_bio->retry_list, &conf->retry_list); conf->nr_queued ++; spin_unlock_irqrestore(&conf->device_lock, flags); /* wake up frozen array... */ wake_up(&conf->wait_barrier); md_wakeup_thread(mddev->thread);} /* * raid_end_bio_io() is called when we have finished servicing a mirrored * operation and are ready to return a success/failure code to the buffer * cache layer. */static void raid_end_bio_io(struct r10bio *r10_bio){ struct bio *bio = r10_bio->master_bio; struct r10conf *conf = r10_bio->mddev->private; bool returned = true; if (!test_and_set_bit(R10BIO_Returned, &r10_bio->state)) { if (!test_bit(R10BIO_Uptodate, &r10_bio->state)) bio->bi_status = BLK_STS_IOERR; returned = false; } free_r10bio(r10_bio); if (!returned) bio_endio(bio); /* * Wake up any possible resync thread that waits for the device * to go idle. */ allow_barrier(conf);} /* * Update disk head position estimator based on IRQ completion info. */static inline void update_head_pos(int slot, struct r10bio *r10_bio){ struct r10conf *conf = r10_bio->mddev->private; conf->mirrors[r10_bio->devs[slot].devnum].head_position = r10_bio->devs[slot].addr + (r10_bio->sectors);} /* * Find the disk number which triggered given bio */static int find_bio_disk(struct r10conf *conf, struct r10bio *r10_bio, struct bio *bio, int *slotp, int *replp){ int slot; int repl = 0; for (slot = 0; slot < conf->geo.raid_disks; slot++) { if (r10_bio->devs[slot].bio == bio) break; if (r10_bio->devs[slot].repl_bio == bio) { repl = 1; break; } } update_head_pos(slot, r10_bio); if (slotp) *slotp = slot; if (replp) *replp = repl; return r10_bio->devs[slot].devnum;} static void raid10_end_read_request(struct bio *bio){ int uptodate = !bio->bi_status; struct r10bio *r10_bio = bio->bi_private; int slot; struct md_rdev *rdev; struct r10conf *conf = r10_bio->mddev->private; slot = r10_bio->read_slot; rdev = r10_bio->devs[slot].rdev; /* * this branch is our 'one mirror IO has finished' event handler: */ update_head_pos(slot, r10_bio); if (uptodate) { /* * Set R10BIO_Uptodate in our master bio, so that * we will return a good error code to the higher * levels even if IO on some other mirrored buffer fails. * * The 'master' represents the composite IO operation to * user-side. So if something waits for IO, then it will * wait for the 'master' bio. */ set_bit(R10BIO_Uptodate, &r10_bio->state); } else if (!raid1_should_handle_error(bio)) { uptodate = 1; } else { /* If all other devices that store this block have * failed, we want to return the error upwards rather * than fail the last device. Here we redefine * "uptodate" to mean "Don't want to retry" */ if (!_enough(conf, test_bit(R10BIO_Previous, &r10_bio->state), rdev->raid_disk)) uptodate = 1; } if (uptodate) { raid_end_bio_io(r10_bio); rdev_dec_pending(rdev, conf->mddev); } else { /* * oops, read error - keep the refcount on the rdev */ pr_err_ratelimited("md/raid10:%s: %pg: rescheduling sector %llu\n", mdname(conf->mddev), rdev->bdev, (unsigned long long)r10_bio->sector); set_bit(R10BIO_ReadError, &r10_bio->state); reschedule_retry(r10_bio); }} static void close_write(struct r10bio *r10_bio){ struct mddev *mddev = r10_bio->mddev; md_write_end(mddev);} static void one_write_done(struct r10bio *r10_bio){ if (atomic_dec_and_test(&r10_bio->remaining)) { if (test_bit(R10BIO_WriteError, &r10_bio->state)) reschedule_retry(r10_bio); else { close_write(r10_bio); if (test_bit(R10BIO_MadeGood, &r10_bio->state)) reschedule_retry(r10_bio); else raid_end_bio_io(r10_bio); } }} static void raid10_end_write_request(struct bio *bio){ struct r10bio *r10_bio = bio->bi_private; int dev; int dec_rdev = 1; struct r10conf *conf = r10_bio->mddev->private; int slot, repl; struct md_rdev *rdev = NULL; struct bio *to_put = NULL; bool ignore_error = !raid1_should_handle_error(bio) || (bio->bi_status && bio_op(bio) == REQ_OP_DISCARD); dev = find_bio_disk(conf, r10_bio, bio, &slot, &repl); if (repl) rdev = conf->mirrors[dev].replacement; if (!rdev) { smp_rmb(); repl = 0; rdev = conf->mirrors[dev].rdev; } /* * this branch is our 'one mirror IO has finished' event handler: */ if (bio->bi_status && !ignore_error) { if (repl) /* Never record new bad blocks to replacement, * just fail it. */ md_error(rdev->mddev, rdev); else { set_bit(WriteErrorSeen, &rdev->flags); if (!test_and_set_bit(WantReplacement, &rdev->flags))Lines 1–500 of 5137. Load more
// SPDX-License-Identifier: GPL-2.0-or-later /* * raid10.c : Multiple Devices driver for Linux * * Copyright (C) 2000-2004 Neil Brown * * RAID-10 support for md. * * Base on code in raid1.c. See raid1.c for further copyright information. */ #include <linux/slab.h> #include <linux/delay.h> #include <linux/blkdev.h> #include <linux/module.h> #include <linux/seq_file.h> #include <linux/ratelimit.h> #include <linux/kthread.h> #include <linux/raid/md_p.h> #include <trace/events/block.h> #include "md.h" #define RAID_1_10_NAME "raid10" #include "raid10.h" #include "raid0.h" #include "md-bitmap.h" #include "md-cluster.h" /* * RAID10 provides a combination of RAID0 and RAID1 functionality. * The layout of data is defined by * chunk_size * raid_disks * near_copies (stored in low byte of layout) * far_copies (stored in second byte of layout) * far_offset (stored in bit 16 of layout ) * use_far_sets (stored in bit 17 of layout ) * use_far_sets_bugfixed (stored in bit 18 of layout ) * * The data to be stored is divided into chunks using chunksize. Each device * is divided into far_copies sections. In each section, chunks are laid out * in a style similar to raid0, but near_copies copies of each chunk is stored * (each on a different drive). The starting device for each section is offset * near_copies from the starting device of the previous section. Thus there * are (near_copies * far_copies) of each chunk, and each is on a different * drive. near_copies and far_copies must be at least one, and their product * is at most raid_disks. * * If far_offset is true, then the far_copies are handled a bit differently. * The copies are still in different stripes, but instead of being very far * apart on disk, there are adjacent stripes. * * The far and offset algorithms are handled slightly differently if * 'use_far_sets' is true. In this case, the array's devices are grouped into * sets that are (near_copies * far_copies) in size. The far copied stripes * are still shifted by 'near_copies' devices, but this shifting stays confined * to the set rather than the entire array. This is done to improve the number * of device combinations that can fail without causing the array to fail. * Example 'far' algorithm w/o 'use_far_sets' (each letter represents a chunk * on a device): * A B C D A B C D E * ... ... * D A B C E A B C D * Example 'far' algorithm w/ 'use_far_sets' enabled (sets illustrated w/ []'s): * [A B] [C D] [A B] [C D E] * |...| |...| |...| | ... | * [B A] [D C] [B A] [E C D] */ static void allow_barrier(struct r10conf *conf); static void lower_barrier(struct r10conf *conf); static int _enough(struct r10conf *conf, int previous, int ignore); static int enough(struct r10conf *conf, int ignore); static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr, int *skipped); static void reshape_request_write(struct mddev *mddev, struct r10bio *r10_bio); static void end_reshape_write(struct bio *bio); static void end_reshape(struct r10conf *conf); #include "raid1-10.c" #define NULL_CMD #define cmd_before(conf, cmd) \ do { \ write_sequnlock_irq(&(conf)->resync_lock); \ cmd; \ } while (0) #define cmd_after(conf) write_seqlock_irq(&(conf)->resync_lock) #define wait_event_barrier_cmd(conf, cond, cmd) \ wait_event_cmd((conf)->wait_barrier, cond, cmd_before(conf, cmd), \ cmd_after(conf)) #define wait_event_barrier(conf, cond) \ wait_event_barrier_cmd(conf, cond, NULL_CMD) /* * for resync bio, r10bio pointer can be retrieved from the per-bio * 'struct resync_pages'. */ static inline struct r10bio *get_resync_r10bio(struct bio *bio) { return get_resync_pages(bio)->raid_bio; } static inline int calc_r10bio_size(unsigned int raid_disks) { return offsetof(struct r10bio, devs[raid_disks]); } static mempool_t *create_r10bio_pool(unsigned int raid_disks) { int size = calc_r10bio_size(raid_disks); return mempool_create_kmalloc_pool(NR_RAID_BIOS, size); } static struct r10bio *alloc_r10bio(unsigned int raid_disks, gfp_t gfp_flags) { int size = calc_r10bio_size(raid_disks); /* allocate a r10bio sized for current geometry */ return kzalloc(size, gfp_flags); } #define RESYNC_SECTORS (RESYNC_BLOCK_SIZE >> 9) /* amount of memory to reserve for resync requests */ #define RESYNC_WINDOW (1024*1024) /* maximum number of concurrent requests, memory permitting */ #define RESYNC_DEPTH (32*1024*1024/RESYNC_BLOCK_SIZE) #define CLUSTER_RESYNC_WINDOW (32 * RESYNC_WINDOW) #define CLUSTER_RESYNC_WINDOW_SECTORS (CLUSTER_RESYNC_WINDOW >> 9) /* * When performing a resync, we need to read and compare, so * we need as many pages are there are copies. * When performing a recovery, we need 2 bios, one for read, * one for write (we recover only one drive per r10buf) * */ static void * r10buf_pool_alloc(gfp_t gfp_flags, void *data) { struct r10conf *conf = data; struct r10bio *r10_bio; struct bio *bio; int j; int nalloc, nalloc_rp; struct resync_pages *rps; r10_bio = alloc_r10bio(conf->geo.raid_disks, gfp_flags); if (!r10_bio) return NULL; if (test_bit(MD_RECOVERY_SYNC, &conf->mddev->recovery) || test_bit(MD_RECOVERY_RESHAPE, &conf->mddev->recovery)) nalloc = conf->copies; /* resync */ else nalloc = 2; /* recovery */ /* allocate once for all bios */ if (!conf->have_replacement) nalloc_rp = nalloc; else nalloc_rp = nalloc * 2; rps = kmalloc_objs(struct resync_pages, nalloc_rp, gfp_flags); if (!rps) goto out_free_r10bio; /* * Allocate bios. */ for (j = nalloc ; j-- ; ) { bio = bio_kmalloc(RESYNC_PAGES, gfp_flags); if (!bio) goto out_free_bio; bio_init_inline(bio, NULL, RESYNC_PAGES, 0); r10_bio->devs[j].bio = bio; if (!conf->have_replacement) continue; bio = bio_kmalloc(RESYNC_PAGES, gfp_flags); if (!bio) goto out_free_bio; bio_init_inline(bio, NULL, RESYNC_PAGES, 0); r10_bio->devs[j].repl_bio = bio; } /* * Allocate RESYNC_PAGES data pages and attach them * where needed. */ for (j = 0; j < nalloc; j++) { struct bio *rbio = r10_bio->devs[j].repl_bio; struct resync_pages *rp, *rp_repl; rp = &rps[j]; if (rbio) rp_repl = &rps[nalloc + j]; bio = r10_bio->devs[j].bio; if (!j || test_bit(MD_RECOVERY_SYNC, &conf->mddev->recovery)) { if (resync_alloc_pages(rp, gfp_flags)) goto out_free_pages; } else { memcpy(rp, &rps[0], sizeof(*rp)); resync_get_all_pages(rp); } rp->raid_bio = r10_bio; bio->bi_private = rp; if (rbio) { memcpy(rp_repl, rp, sizeof(*rp)); rbio->bi_private = rp_repl; } } return r10_bio; out_free_pages: while (--j >= 0) resync_free_pages(&rps[j]); j = 0; out_free_bio: for ( ; j < nalloc; j++) { if (r10_bio->devs[j].bio) bio_uninit(r10_bio->devs[j].bio); kfree(r10_bio->devs[j].bio); if (r10_bio->devs[j].repl_bio) bio_uninit(r10_bio->devs[j].repl_bio); kfree(r10_bio->devs[j].repl_bio); } kfree(rps); out_free_r10bio: rbio_pool_free(r10_bio, conf); return NULL; } static void r10buf_pool_free(void *__r10_bio, void *data) { struct r10conf *conf = data; struct r10bio *r10bio = __r10_bio; int j; struct resync_pages *rp = NULL; for (j = conf->copies; j--; ) { struct bio *bio = r10bio->devs[j].bio; if (bio) { rp = get_resync_pages(bio); resync_free_pages(rp); bio_uninit(bio); kfree(bio); } bio = r10bio->devs[j].repl_bio; if (bio) { bio_uninit(bio); kfree(bio); } } /* resync pages array stored in the 1st bio's .bi_private */ kfree(rp); rbio_pool_free(r10bio, conf); } static void put_all_bios(struct r10conf *conf, struct r10bio *r10_bio) { int i; for (i = 0; i < conf->geo.raid_disks; i++) { struct bio **bio = & r10_bio->devs[i].bio; if (!BIO_SPECIAL(*bio)) bio_put(*bio); *bio = NULL; bio = &r10_bio->devs[i].repl_bio; if (r10_bio->read_slot < 0 && !BIO_SPECIAL(*bio)) bio_put(*bio); *bio = NULL; } } static void free_r10bio(struct r10bio *r10_bio) { struct r10conf *conf = r10_bio->mddev->private; put_all_bios(conf, r10_bio); mempool_free(r10_bio, conf->r10bio_pool); } static void put_buf(struct r10bio *r10_bio) { struct r10conf *conf = r10_bio->mddev->private; mempool_free(r10_bio, &conf->r10buf_pool); lower_barrier(conf); } static void wake_up_barrier(struct r10conf *conf) { if (wq_has_sleeper(&conf->wait_barrier)) wake_up(&conf->wait_barrier); } static void reschedule_retry(struct r10bio *r10_bio) { unsigned long flags; struct mddev *mddev = r10_bio->mddev; struct r10conf *conf = mddev->private; spin_lock_irqsave(&conf->device_lock, flags); list_add(&r10_bio->retry_list, &conf->retry_list); conf->nr_queued ++; spin_unlock_irqrestore(&conf->device_lock, flags); /* wake up frozen array... */ wake_up(&conf->wait_barrier); md_wakeup_thread(mddev->thread); } /* * raid_end_bio_io() is called when we have finished servicing a mirrored * operation and are ready to return a success/failure code to the buffer * cache layer. */ static void raid_end_bio_io(struct r10bio *r10_bio) { struct bio *bio = r10_bio->master_bio; struct r10conf *conf = r10_bio->mddev->private; bool returned = true; if (!test_and_set_bit(R10BIO_Returned, &r10_bio->state)) { if (!test_bit(R10BIO_Uptodate, &r10_bio->state)) bio->bi_status = BLK_STS_IOERR; returned = false; } free_r10bio(r10_bio); if (!returned) bio_endio(bio); /* * Wake up any possible resync thread that waits for the device * to go idle. */ allow_barrier(conf); } /* * Update disk head position estimator based on IRQ completion info. */ static inline void update_head_pos(int slot, struct r10bio *r10_bio) { struct r10conf *conf = r10_bio->mddev->private; conf->mirrors[r10_bio->devs[slot].devnum].head_position = r10_bio->devs[slot].addr + (r10_bio->sectors); } /* * Find the disk number which triggered given bio */ static int find_bio_disk(struct r10conf *conf, struct r10bio *r10_bio, struct bio *bio, int *slotp, int *replp) { int slot; int repl = 0; for (slot = 0; slot < conf->geo.raid_disks; slot++) { if (r10_bio->devs[slot].bio == bio) break; if (r10_bio->devs[slot].repl_bio == bio) { repl = 1; break; } } update_head_pos(slot, r10_bio); if (slotp) *slotp = slot; if (replp) *replp = repl; return r10_bio->devs[slot].devnum; } static void raid10_end_read_request(struct bio *bio) { int uptodate = !bio->bi_status; struct r10bio *r10_bio = bio->bi_private; int slot; struct md_rdev *rdev; struct r10conf *conf = r10_bio->mddev->private; slot = r10_bio->read_slot; rdev = r10_bio->devs[slot].rdev; /* * this branch is our 'one mirror IO has finished' event handler: */ update_head_pos(slot, r10_bio); if (uptodate) { /* * Set R10BIO_Uptodate in our master bio, so that * we will return a good error code to the higher * levels even if IO on some other mirrored buffer fails. * * The 'master' represents the composite IO operation to * user-side. So if something waits for IO, then it will * wait for the 'master' bio. */ set_bit(R10BIO_Uptodate, &r10_bio->state); } else if (!raid1_should_handle_error(bio)) { uptodate = 1; } else { /* If all other devices that store this block have * failed, we want to return the error upwards rather * than fail the last device. Here we redefine * "uptodate" to mean "Don't want to retry" */ if (!_enough(conf, test_bit(R10BIO_Previous, &r10_bio->state), rdev->raid_disk)) uptodate = 1; } if (uptodate) { raid_end_bio_io(r10_bio); rdev_dec_pending(rdev, conf->mddev); } else { /* * oops, read error - keep the refcount on the rdev */ pr_err_ratelimited("md/raid10:%s: %pg: rescheduling sector %llu\n", mdname(conf->mddev), rdev->bdev, (unsigned long long)r10_bio->sector); set_bit(R10BIO_ReadError, &r10_bio->state); reschedule_retry(r10_bio); } } static void close_write(struct r10bio *r10_bio) { struct mddev *mddev = r10_bio->mddev; md_write_end(mddev); } static void one_write_done(struct r10bio *r10_bio) { if (atomic_dec_and_test(&r10_bio->remaining)) { if (test_bit(R10BIO_WriteError, &r10_bio->state)) reschedule_retry(r10_bio); else { close_write(r10_bio); if (test_bit(R10BIO_MadeGood, &r10_bio->state)) reschedule_retry(r10_bio); else raid_end_bio_io(r10_bio); } } } static void raid10_end_write_request(struct bio *bio) { struct r10bio *r10_bio = bio->bi_private; int dev; int dec_rdev = 1; struct r10conf *conf = r10_bio->mddev->private; int slot, repl; struct md_rdev *rdev = NULL; struct bio *to_put = NULL; bool ignore_error = !raid1_should_handle_error(bio) || (bio->bi_status && bio_op(bio) == REQ_OP_DISCARD); dev = find_bio_disk(conf, r10_bio, bio, &slot, &repl); if (repl) rdev = conf->mirrors[dev].replacement; if (!rdev) { smp_rmb(); repl = 0; rdev = conf->mirrors[dev].rdev; } /* * this branch is our 'one mirror IO has finished' event handler: */ if (bio->bi_status && !ignore_error) { if (repl) /* Never record new bad blocks to replacement, * just fail it. */ md_error(rdev->mddev, rdev); else { set_bit(WriteErrorSeen, &rdev->flags); if (!test_and_set_bit(WantReplacement, &rdev->flags))