*/
#define NR_RAID10_BIOS 256
-/* When there are this many requests queue to be written by
+/* 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)
+/* When we successfully write to a known bad-block, we need to remove the
+ * bad-block marking which must be done from process context. So we record
+ * the success by setting devs[n].bio to IO_MADE_GOOD
+ */
+#define IO_MADE_GOOD ((struct bio *)2)
+
+#define BIO_SPECIAL(bio) ((unsigned long)bio <= 2)
+
+/* When there are this many requests queued to be written by
* the raid10 thread, we become 'congested' to provide back-pressure
* for writeback.
*/
int sectors = r10_bio->sectors;
int best_good_sectors;
sector_t new_distance, best_dist;
- struct md_rdev *rdev, *best_rdev;
+ struct md_rdev *best_rdev, *rdev = NULL;
int do_balance;
int best_slot;
struct geom *geo = &conf->geo;
bio_list_add(&conf->pending_bio_list, mbio);
conf->pending_count++;
spin_unlock_irqrestore(&conf->device_lock, flags);
- if (!mddev_check_plugged(mddev, 0, 0))
+ if (!mddev_check_plugged(mddev))
md_wakeup_thread(mddev->thread);
if (!r10_bio->devs[i].repl_bio)
static void print_conf(struct r10conf *conf)
{
int i;
- struct mirror_info *tmp;
+ struct raid10_info *tmp;
printk(KERN_DEBUG "RAID10 conf printout:\n");
if (!conf) {
{
int i;
struct r10conf *conf = mddev->private;
- struct mirror_info *tmp;
+ struct raid10_info *tmp;
int count = 0;
unsigned long flags;
else
mirror = first;
for ( ; mirror <= last ; mirror++) {
- struct mirror_info *p = &conf->mirrors[mirror];
+ struct raid10_info *p = &conf->mirrors[mirror];
if (p->recovery_disabled == mddev->recovery_disabled)
continue;
if (p->rdev) {
int err = 0;
int number = rdev->raid_disk;
struct md_rdev **rdevp;
- struct mirror_info *p = conf->mirrors + number;
+ struct raid10_info *p = conf->mirrors + number;
print_conf(conf);
if (rdev == p->rdev)
sector_t sect;
int must_sync;
int any_working;
- struct mirror_info *mirror = &conf->mirrors[i];
+ struct raid10_info *mirror = &conf->mirrors[i];
if ((mirror->rdev == NULL ||
test_bit(In_sync, &mirror->rdev->flags))
goto out;
/* FIXME calc properly */
- conf->mirrors = kzalloc(sizeof(struct mirror_info)*(mddev->raid_disks +
+ conf->mirrors = kzalloc(sizeof(struct raid10_info)*(mddev->raid_disks +
max(0,mddev->delta_disks)),
GFP_KERNEL);
if (!conf->mirrors)
{
struct r10conf *conf;
int i, disk_idx, chunk_size;
- struct mirror_info *disk;
+ struct raid10_info *disk;
struct md_rdev *rdev;
sector_t size;
sector_t min_offset_diff = 0;
if (mddev->delta_disks > 0) {
/* allocate new 'mirrors' list */
conf->mirrors_new = kzalloc(
- sizeof(struct mirror_info)
+ sizeof(struct raid10_info)
*(mddev->raid_disks +
mddev->delta_disks),
GFP_KERNEL);
spin_lock_irq(&conf->device_lock);
if (conf->mirrors_new) {
memcpy(conf->mirrors_new, conf->mirrors,
- sizeof(struct mirror_info)*conf->prev.raid_disks);
+ sizeof(struct raid10_info)*conf->prev.raid_disks);
smp_mb();
kfree(conf->mirrors_old); /* FIXME and elsewhere */
conf->mirrors_old = conf->mirrors;