Commit 82081640 authored by Neil Brown's avatar Neil Brown Committed by Trond Myklebust

[PATCH] MD - Improve handling of spares in md

Improve handling of spares in md

- hot_remove_disk is given the raid_disk rather than descriptor number
  so that it can find the device in internal array directly, no search.
- spare_inactive now uses mddev->spare->raid_disk instead of
  mddev->spare->number so it can find the device directly without searching
- spare_write does not need number.  It can use mddev->spare->raid_disk as above.
- spare_active does not need &mddev->spare.  It finds the descriptor directly
  and fixes it without this pointer
parent 03aa5c1c
...@@ -2202,7 +2202,7 @@ static int hot_remove_disk(mddev_t * mddev, kdev_t dev) ...@@ -2202,7 +2202,7 @@ static int hot_remove_disk(mddev_t * mddev, kdev_t dev)
return -EINVAL; return -EINVAL;
} }
err = mddev->pers->hot_remove_disk(mddev, disk->number); err = mddev->pers->hot_remove_disk(mddev, disk->raid_disk);
if (err == -EBUSY) { if (err == -EBUSY) {
MD_BUG(); MD_BUG();
goto busy; goto busy;
...@@ -3314,8 +3314,7 @@ void md_do_recovery(void *data) ...@@ -3314,8 +3314,7 @@ void md_do_recovery(void *data)
goto unlock; goto unlock;
/* success...*/ /* success...*/
if (mddev->spare) { if (mddev->spare) {
mddev->pers->spare_active(mddev, mddev->pers->spare_active(mddev);
&mddev->spare);
mark_disk_sync(mddev->spare); mark_disk_sync(mddev->spare);
mark_disk_active(mddev->spare); mark_disk_active(mddev->spare);
sb->active_disks++; sb->active_disks++;
...@@ -3359,8 +3358,7 @@ void md_do_recovery(void *data) ...@@ -3359,8 +3358,7 @@ void md_do_recovery(void *data)
mddev->recovery_running = 0; mddev->recovery_running = 0;
} else { } else {
if (mddev->spare) if (mddev->spare)
mddev->pers->spare_write(mddev, mddev->pers->spare_write(mddev);
mddev->spare->number);
mddev->recovery_running = 1; mddev->recovery_running = 1;
md_wakeup_thread(mddev->sync_thread); md_wakeup_thread(mddev->sync_thread);
} }
......
...@@ -333,16 +333,14 @@ static int multipath_remove_disk(mddev_t *mddev, int number) ...@@ -333,16 +333,14 @@ static int multipath_remove_disk(mddev_t *mddev, int number)
{ {
multipath_conf_t *conf = mddev->private; multipath_conf_t *conf = mddev->private;
int err = 1; int err = 1;
int i; struct multipath_info *p = conf->multipaths + number;
print_multipath_conf(conf); print_multipath_conf(conf);
spin_lock_irq(&conf->device_lock); spin_lock_irq(&conf->device_lock);
for (i = 0; i < MD_SB_DISKS; i++) { if (p->used_slot) {
struct multipath_info *p = conf->multipaths + i;
if (p->used_slot && (p->number == number)) {
if (p->operational) { if (p->operational) {
printk(KERN_ERR "hot-remove-disk, slot %d is identified to be the requested disk (number %d), but is still operational!\n", i, number); printk(KERN_ERR "hot-remove-disk, slot %d is identified but is still operational!\n", number);
err = -EBUSY; err = -EBUSY;
goto abort; goto abort;
} }
...@@ -350,8 +348,6 @@ static int multipath_remove_disk(mddev_t *mddev, int number) ...@@ -350,8 +348,6 @@ static int multipath_remove_disk(mddev_t *mddev, int number)
p->used_slot = 0; p->used_slot = 0;
conf->nr_disks--; conf->nr_disks--;
err = 0; err = 0;
break;
}
} }
if (err) if (err)
MD_BUG(); MD_BUG();
......
...@@ -657,19 +657,7 @@ static void close_sync(conf_t *conf) ...@@ -657,19 +657,7 @@ static void close_sync(conf_t *conf)
conf->r1buf_pool = NULL; conf->r1buf_pool = NULL;
} }
static mirror_info_t *find_spare(mddev_t *mddev, int number) static int raid1_spare_active(mddev_t *mddev)
{
conf_t *conf = mddev->private;
int i;
for (i = conf->raid_disks; i < MD_SB_DISKS; i++) {
mirror_info_t *p = conf->mirrors + i;
if (p->spare && p->number == number)
return p;
}
return NULL;
}
static int raid1_spare_active(mddev_t *mddev, mdp_disk_t **d)
{ {
int err = 0; int err = 0;
int i, failed_disk = -1, spare_disk = -1; int i, failed_disk = -1, spare_disk = -1;
...@@ -706,18 +694,7 @@ static int raid1_spare_active(mddev_t *mddev, mdp_disk_t **d) ...@@ -706,18 +694,7 @@ static int raid1_spare_active(mddev_t *mddev, mdp_disk_t **d)
* Find the spare disk ... (can only be in the 'high' * Find the spare disk ... (can only be in the 'high'
* area of the array) * area of the array)
*/ */
for (i = conf->raid_disks; i < MD_SB_DISKS; i++) { spare_disk = mddev->spare->raid_disk;
tmp = conf->mirrors + i;
if (tmp->spare && tmp->number == (*d)->number) {
spare_disk = i;
break;
}
}
if (spare_disk == -1) {
MD_BUG();
err = 1;
goto abort;
}
sdisk = conf->mirrors + spare_disk; sdisk = conf->mirrors + spare_disk;
fdisk = conf->mirrors + failed_disk; fdisk = conf->mirrors + failed_disk;
...@@ -725,7 +702,7 @@ static int raid1_spare_active(mddev_t *mddev, mdp_disk_t **d) ...@@ -725,7 +702,7 @@ static int raid1_spare_active(mddev_t *mddev, mdp_disk_t **d)
spare_desc = &sb->disks[sdisk->number]; spare_desc = &sb->disks[sdisk->number];
failed_desc = &sb->disks[fdisk->number]; failed_desc = &sb->disks[fdisk->number];
if (spare_desc != *d || spare_desc->raid_disk != sdisk->raid_disk || if (spare_desc->raid_disk != sdisk->raid_disk ||
sdisk->raid_disk != spare_disk || fdisk->raid_disk != failed_disk || sdisk->raid_disk != spare_disk || fdisk->raid_disk != failed_disk ||
failed_desc->raid_disk != fdisk->raid_disk) { failed_desc->raid_disk != fdisk->raid_disk) {
MD_BUG(); MD_BUG();
...@@ -762,8 +739,6 @@ static int raid1_spare_active(mddev_t *mddev, mdp_disk_t **d) ...@@ -762,8 +739,6 @@ static int raid1_spare_active(mddev_t *mddev, mdp_disk_t **d)
xchg_values(spare_desc->number, failed_desc->number); xchg_values(spare_desc->number, failed_desc->number);
xchg_values(sdisk->number, fdisk->number); xchg_values(sdisk->number, fdisk->number);
*d = failed_desc;
if (!sdisk->bdev) if (!sdisk->bdev)
sdisk->used_slot = 0; sdisk->used_slot = 0;
/* /*
...@@ -794,7 +769,7 @@ static int raid1_spare_inactive(mddev_t *mddev) ...@@ -794,7 +769,7 @@ static int raid1_spare_inactive(mddev_t *mddev)
print_conf(conf); print_conf(conf);
spin_lock_irq(&conf->device_lock); spin_lock_irq(&conf->device_lock);
p = find_spare(mddev, mddev->spare->number); p = conf->mirrors + mddev->spare->raid_disk;
if (p) { if (p) {
p->operational = 0; p->operational = 0;
p->write_only = 0; p->write_only = 0;
...@@ -807,7 +782,7 @@ static int raid1_spare_inactive(mddev_t *mddev) ...@@ -807,7 +782,7 @@ static int raid1_spare_inactive(mddev_t *mddev)
return err; return err;
} }
static int raid1_spare_write(mddev_t *mddev, int number) static int raid1_spare_write(mddev_t *mddev)
{ {
conf_t *conf = mddev->private; conf_t *conf = mddev->private;
mirror_info_t *p; mirror_info_t *p;
...@@ -815,7 +790,7 @@ static int raid1_spare_write(mddev_t *mddev, int number) ...@@ -815,7 +790,7 @@ static int raid1_spare_write(mddev_t *mddev, int number)
print_conf(conf); print_conf(conf);
spin_lock_irq(&conf->device_lock); spin_lock_irq(&conf->device_lock);
p = find_spare(mddev, number); p = conf->mirrors + mddev->spare->raid_disk;
if (p) { if (p) {
p->operational = 1; p->operational = 1;
p->write_only = 1; p->write_only = 1;
...@@ -871,25 +846,19 @@ static int raid1_remove_disk(mddev_t *mddev, int number) ...@@ -871,25 +846,19 @@ static int raid1_remove_disk(mddev_t *mddev, int number)
{ {
conf_t *conf = mddev->private; conf_t *conf = mddev->private;
int err = 1; int err = 1;
int i; mirror_info_t *p = conf->mirrors+ number;
print_conf(conf); print_conf(conf);
spin_lock_irq(&conf->device_lock); spin_lock_irq(&conf->device_lock);
for (i = 0; i < MD_SB_DISKS; i++) { if (p->used_slot) {
mirror_info_t *p = conf->mirrors + i;
if (p->used_slot && (p->number == number)) {
if (p->operational) { if (p->operational) {
err = -EBUSY; err = -EBUSY;
goto abort; goto abort;
} }
if (p->spare && (i < conf->raid_disks))
break;
p->bdev = NULL; p->bdev = NULL;
p->used_slot = 0; p->used_slot = 0;
conf->nr_disks--; conf->nr_disks--;
err = 0; err = 0;
break;
}
} }
if (err) if (err)
MD_BUG(); MD_BUG();
......
...@@ -1686,19 +1686,7 @@ static void print_raid5_conf (raid5_conf_t *conf) ...@@ -1686,19 +1686,7 @@ static void print_raid5_conf (raid5_conf_t *conf)
} }
} }
static struct disk_info *find_spare(mddev_t *mddev, int number) static int raid5_spare_active(mddev_t *mddev)
{
raid5_conf_t *conf = mddev->private;
int i;
for (i = conf->raid_disks; i < MD_SB_DISKS; i++) {
struct disk_info *p = conf->disks + i;
if (p->spare && p->number == number)
return p;
}
return NULL;
}
static int raid5_spare_active(mddev_t *mddev, mdp_disk_t **d)
{ {
int err = 0; int err = 0;
int i, failed_disk=-1, spare_disk=-1; int i, failed_disk=-1, spare_disk=-1;
...@@ -1727,18 +1715,7 @@ static int raid5_spare_active(mddev_t *mddev, mdp_disk_t **d) ...@@ -1727,18 +1715,7 @@ static int raid5_spare_active(mddev_t *mddev, mdp_disk_t **d)
* Find the spare disk ... (can only be in the 'high' * Find the spare disk ... (can only be in the 'high'
* area of the array) * area of the array)
*/ */
for (i = conf->raid_disks; i < MD_SB_DISKS; i++) { spare_disk = mddev->spare->raid_disk;
tmp = conf->disks + i;
if (tmp->spare && tmp->number == (*d)->number) {
spare_disk = i;
break;
}
}
if (spare_disk == -1) {
MD_BUG();
err = 1;
goto abort;
}
if (!conf->spare) { if (!conf->spare) {
MD_BUG(); MD_BUG();
...@@ -1751,7 +1728,7 @@ static int raid5_spare_active(mddev_t *mddev, mdp_disk_t **d) ...@@ -1751,7 +1728,7 @@ static int raid5_spare_active(mddev_t *mddev, mdp_disk_t **d)
spare_desc = &sb->disks[sdisk->number]; spare_desc = &sb->disks[sdisk->number];
failed_desc = &sb->disks[fdisk->number]; failed_desc = &sb->disks[fdisk->number];
if (spare_desc != *d || spare_desc->raid_disk != sdisk->raid_disk || if ( spare_desc->raid_disk != sdisk->raid_disk ||
sdisk->raid_disk != spare_disk || fdisk->raid_disk != failed_disk || sdisk->raid_disk != spare_disk || fdisk->raid_disk != failed_disk ||
failed_desc->raid_disk != fdisk->raid_disk) { failed_desc->raid_disk != fdisk->raid_disk) {
MD_BUG(); MD_BUG();
...@@ -1788,8 +1765,6 @@ static int raid5_spare_active(mddev_t *mddev, mdp_disk_t **d) ...@@ -1788,8 +1765,6 @@ static int raid5_spare_active(mddev_t *mddev, mdp_disk_t **d)
xchg_values(spare_desc->number, failed_desc->number); xchg_values(spare_desc->number, failed_desc->number);
xchg_values(sdisk->number, fdisk->number); xchg_values(sdisk->number, fdisk->number);
*d = failed_desc;
if (!sdisk->bdev) if (!sdisk->bdev)
sdisk->used_slot = 0; sdisk->used_slot = 0;
...@@ -1821,7 +1796,7 @@ static int raid5_spare_inactive(mddev_t *mddev) ...@@ -1821,7 +1796,7 @@ static int raid5_spare_inactive(mddev_t *mddev)
print_raid5_conf(conf); print_raid5_conf(conf);
spin_lock_irq(&conf->device_lock); spin_lock_irq(&conf->device_lock);
p = find_spare(mddev, mddev->spare->number); p = conf->disks + mddev->spare->raid_disk;
if (p) { if (p) {
p->operational = 0; p->operational = 0;
p->write_only = 0; p->write_only = 0;
...@@ -1836,7 +1811,7 @@ static int raid5_spare_inactive(mddev_t *mddev) ...@@ -1836,7 +1811,7 @@ static int raid5_spare_inactive(mddev_t *mddev)
return err; return err;
} }
static int raid5_spare_write(mddev_t *mddev, int number) static int raid5_spare_write(mddev_t *mddev)
{ {
raid5_conf_t *conf = mddev->private; raid5_conf_t *conf = mddev->private;
struct disk_info *p; struct disk_info *p;
...@@ -1844,7 +1819,7 @@ static int raid5_spare_write(mddev_t *mddev, int number) ...@@ -1844,7 +1819,7 @@ static int raid5_spare_write(mddev_t *mddev, int number)
print_raid5_conf(conf); print_raid5_conf(conf);
spin_lock_irq(&conf->device_lock); spin_lock_irq(&conf->device_lock);
p = find_spare(mddev, number); p = conf->disks + mddev->spare->raid_disk;
if (p && !conf->spare) { if (p && !conf->spare) {
p->operational = 1; p->operational = 1;
p->write_only = 1; p->write_only = 1;
...@@ -1862,25 +1837,19 @@ static int raid5_remove_disk(mddev_t *mddev, int number) ...@@ -1862,25 +1837,19 @@ static int raid5_remove_disk(mddev_t *mddev, int number)
{ {
raid5_conf_t *conf = mddev->private; raid5_conf_t *conf = mddev->private;
int err = 1; int err = 1;
int i; struct disk_info *p = conf->disks + number;
print_raid5_conf(conf); print_raid5_conf(conf);
spin_lock_irq(&conf->device_lock); spin_lock_irq(&conf->device_lock);
for (i = 0; i < MD_SB_DISKS; i++) { if (p->used_slot) {
struct disk_info *p = conf->disks + i;
if (p->used_slot && p->number == number) {
if (p->operational) { if (p->operational) {
err = -EBUSY; err = -EBUSY;
goto abort; goto abort;
} }
if (p->spare && i < conf->raid_disks)
break;
p->bdev = NULL; p->bdev = NULL;
p->used_slot = 0; p->used_slot = 0;
err = 0; err = 0;
break;
}
} }
if (err) if (err)
MD_BUG(); MD_BUG();
......
...@@ -207,9 +207,9 @@ struct mdk_personality_s ...@@ -207,9 +207,9 @@ struct mdk_personality_s
int (*error_handler)(mddev_t *mddev, struct block_device *bdev); int (*error_handler)(mddev_t *mddev, struct block_device *bdev);
int (*hot_add_disk) (mddev_t *mddev, mdp_disk_t *descriptor, mdk_rdev_t *rdev); int (*hot_add_disk) (mddev_t *mddev, mdp_disk_t *descriptor, mdk_rdev_t *rdev);
int (*hot_remove_disk) (mddev_t *mddev, int number); int (*hot_remove_disk) (mddev_t *mddev, int number);
int (*spare_write) (mddev_t *mddev, int number); int (*spare_write) (mddev_t *mddev);
int (*spare_inactive) (mddev_t *mddev); int (*spare_inactive) (mddev_t *mddev);
int (*spare_active) (mddev_t *mddev, mdp_disk_t **descriptor); int (*spare_active) (mddev_t *mddev);
int (*sync_request)(mddev_t *mddev, sector_t sector_nr, int go_faster); int (*sync_request)(mddev_t *mddev, sector_t sector_nr, int go_faster);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment