Commit 7444c718 authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] md 21 of 22 - Improve handling of MD super blocks

1/ don't free the rdev->sb on an error -- it might be
   accessed again later.  Just wait for the device to be
   exported.
2/ Change md_update_sb to __md_update_sb and have it
   clear the sb_dirty flag.
   New md_update_sb locks the device and calls __md_update_sb
   if sb_dirty.  This avoids any possbile races around
   updating the superblock
parent f7bbc7e1
......@@ -921,12 +921,13 @@ static int sync_sbs(mddev_t * mddev)
return 0;
}
int md_update_sb(mddev_t * mddev)
void __md_update_sb(mddev_t * mddev)
{
int err, count = 100;
struct list_head *tmp;
mdk_rdev_t *rdev;
mddev->sb_dirty = 0;
repeat:
mddev->sb->utime = CURRENT_TIME;
if (!(++mddev->sb->events_lo))
......@@ -948,7 +949,7 @@ int md_update_sb(mddev_t * mddev)
* nonpersistent superblocks
*/
if (mddev->sb->not_persistent)
return 0;
return;
printk(KERN_INFO "md: updating md%d RAID superblock on device\n",
mdidx(mddev));
......@@ -976,9 +977,18 @@ int md_update_sb(mddev_t * mddev)
}
printk(KERN_ERR "md: excessive errors occurred during superblock update, exiting\n");
}
return 0;
}
void md_update_sb(mddev_t *mddev)
{
if (mddev_lock(mddev))
return;
if (mddev->sb_dirty)
__md_update_sb(mddev);
mddev_unlock(mddev);
}
/*
* Import a device. If 'on_disk', then sanity check the superblock
*
......@@ -1648,7 +1658,7 @@ static int do_md_run(mddev_t * mddev)
}
mddev->sb->state &= ~(1 << MD_SB_CLEAN);
md_update_sb(mddev);
__md_update_sb(mddev);
/*
* md_size has units of 1K blocks, which are
......@@ -1770,7 +1780,7 @@ static int do_md_stop(mddev_t * mddev, int ro)
printk(KERN_INFO "md: marking sb clean...\n");
mddev->sb->state |= 1 << MD_SB_CLEAN;
}
md_update_sb(mddev);
__md_update_sb(mddev);
}
if (ro)
set_device_ro(dev, 1);
......@@ -2281,8 +2291,7 @@ static int hot_remove_disk(mddev_t * mddev, kdev_t dev)
remove_descriptor(disk, mddev->sb);
kick_rdev_from_array(rdev);
mddev->sb_dirty = 1;
md_update_sb(mddev);
__md_update_sb(mddev);
return 0;
busy:
......@@ -2393,9 +2402,7 @@ static int hot_add_disk(mddev_t * mddev, kdev_t dev)
mddev->sb->spare_disks++;
mddev->sb->working_disks++;
mddev->sb_dirty = 1;
md_update_sb(mddev);
__md_update_sb(mddev);
/*
* Kick recovery, maybe this spare has to be added to the
......@@ -2918,7 +2925,6 @@ int md_error(mddev_t *mddev, struct block_device *bdev)
return 0;
if (!mddev->pers->error_handler
|| mddev->pers->error_handler(mddev,rdev) <= 0) {
free_disk_sb(rrdev);
rrdev->faulty = 1;
} else
return 1;
......@@ -3423,8 +3429,7 @@ void md_do_recovery(void *data)
sb->active_disks++;
sb->spare_disks--;
}
mddev->sb_dirty = 1;
md_update_sb(mddev);
__md_update_sb(mddev);
mddev->recovery_running = 0;
unlock:
mddev_unlock(mddev);
......
......@@ -699,7 +699,6 @@ static void multipathd (void *data)
mddev = mp_bh->mddev;
if (mddev->sb_dirty) {
printk(KERN_INFO "dirty sb detected, updating.\n");
mddev->sb_dirty = 0;
md_update_sb(mddev);
}
bio = mp_bh->bio;
......
......@@ -1084,7 +1084,6 @@ static void raid1d(void *data)
conf = mddev_to_conf(mddev);
if (mddev->sb_dirty) {
printk(KERN_INFO "raid1: dirty sb detected, updating.\n");
mddev->sb_dirty = 0;
md_update_sb(mddev);
}
bio = r1_bio->master_bio;
......
......@@ -1335,10 +1335,8 @@ static void raid5d (void *data)
handled = 0;
if (mddev->sb_dirty) {
mddev->sb_dirty = 0;
if (mddev->sb_dirty)
md_update_sb(mddev);
}
spin_lock_irq(&conf->device_lock);
while (1) {
struct list_head *first;
......
......@@ -75,7 +75,7 @@ extern mdk_thread_t * md_register_thread (void (*run) (void *data),
extern void md_unregister_thread (mdk_thread_t *thread);
extern void md_wakeup_thread(mdk_thread_t *thread);
extern void md_interrupt_thread (mdk_thread_t *thread);
extern int md_update_sb (mddev_t *mddev);
extern void md_update_sb (mddev_t *mddev);
extern int md_do_sync(mddev_t *mddev, mdp_disk_t *spare);
extern void md_done_sync(mddev_t *mddev, int blocks, int ok);
extern void md_sync_acct(kdev_t dev, unsigned long nr_sectors);
......
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