Commit 1b114450 authored by Neil Brown's avatar Neil Brown Committed by Trond Myklebust

[PATCH] MD - when writing superblock, generate from mddev/rdev info.

when writing superblock, generate from mddev/rdev info.

Rather than relying on the superblock info being kept up-to-date,
we regenerate the superblock from mddev/rdev info before
each write.
parent d58aa811
...@@ -860,44 +860,73 @@ static int write_disk_sb(mdk_rdev_t * rdev) ...@@ -860,44 +860,73 @@ static int write_disk_sb(mdk_rdev_t * rdev)
return 1; return 1;
} }
static void set_this_disk(mddev_t *mddev, mdk_rdev_t *rdev) static int sync_sbs(mddev_t * mddev)
{ {
int i, ok = 0; mdk_rdev_t *rdev;
mdp_disk_t *desc; mdp_super_t *sb;
struct list_head *tmp;
for (i = 0; i < MD_SB_DISKS; i++) { /* make sb->disks match mddev->disks
desc = mddev->sb->disks + i; * 1/ zero out disks
#if 0 * 2/ Add info for each disk, keeping track of highest desc_nr
if (disk_faulty(desc)) { * 3/ any empty disks < highest become removed
if (mk_kdev(desc->major,desc->minor) == rdev->dev) *
ok = 1; * disks[0] gets initialised to REMOVED because
continue; * we cannot be sure from other fields if it has
} * been initialised or not.
#endif */
if (kdev_same(mk_kdev(desc->major,desc->minor), rdev->dev)) { int highest = 0;
rdev->sb->this_disk = *desc; int i;
ok = 1; int active=0, working=0,failed=0,spare=0,nr_disks=0;
break;
sb = mddev->sb;
sb->disks[0].state = (1<<MD_DISK_REMOVED);
ITERATE_RDEV(mddev,rdev,tmp) {
mdp_disk_t *d = &sb->disks[rdev->desc_nr];
nr_disks++;
d->number = rdev->desc_nr;
d->major = major(rdev->dev);
d->minor = minor(rdev->dev);
d->raid_disk = rdev->raid_disk;
if (rdev->faulty) {
d->state = (1<<MD_DISK_FAULTY);
failed++;
} else if (rdev->in_sync) {
d->state = (1<<MD_DISK_ACTIVE);
d->state |= (1<<MD_DISK_SYNC);
active++;
working++;
} else {
d->state = 0;
spare++;
working++;
} }
if (rdev->desc_nr > highest)
highest = rdev->desc_nr;
} }
if (!ok) { /* now set the "removed" bit on any non-trailing holes */
MD_BUG(); for (i=0; i<highest; i++) {
mdp_disk_t *d = &sb->disks[i];
if (d->state == 0 && d->number == 0) {
d->number = i;
d->raid_disk = i;
d->state = (1<<MD_DISK_REMOVED);
} }
} }
sb->nr_disks = nr_disks;
static int sync_sbs(mddev_t * mddev) sb->active_disks = active;
{ sb->working_disks = working;
mdk_rdev_t *rdev; sb->failed_disks = failed;
mdp_super_t *sb; sb->spare_disks = spare;
struct list_head *tmp;
ITERATE_RDEV(mddev,rdev,tmp) { ITERATE_RDEV(mddev,rdev,tmp) {
if (rdev->faulty || rdev->alias_device) if (rdev->faulty || rdev->alias_device)
continue; continue;
sb = rdev->sb; sb = rdev->sb;
*sb = *mddev->sb; *sb = *mddev->sb;
set_this_disk(mddev, rdev); sb->this_disk = sb->disks[rdev->desc_nr];
sb->sb_csum = calc_sb_csum(sb); sb->sb_csum = calc_sb_csum(sb);
} }
return 0; return 0;
......
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