patch-2.4.5 linux/drivers/md/raid5.c
Next file: linux/drivers/media/radio/radio-aimslab.c
Previous file: linux/drivers/md/raid1.c
Back to the patch index
Back to the overall index
- Lines: 212
- Date:
Thu May 24 15:40:59 2001
- Orig file:
v2.4.4/linux/drivers/md/raid5.c
- Orig date:
Fri Feb 9 11:30:23 2001
diff -u --recursive --new-file v2.4.4/linux/drivers/md/raid5.c linux/drivers/md/raid5.c
@@ -156,9 +156,9 @@
return 1;
memset(bh, 0, sizeof (struct buffer_head));
init_waitqueue_head(&bh->b_wait);
- page = alloc_page(priority);
- bh->b_data = page_address(page);
- if (!bh->b_data) {
+ if ((page = alloc_page(priority)))
+ bh->b_data = page_address(page);
+ else {
kfree(bh);
return 1;
}
@@ -412,7 +412,7 @@
spin_lock_irqsave(&conf->device_lock, flags);
}
} else {
- md_error(mddev_to_kdev(conf->mddev), bh->b_dev);
+ md_error(conf->mddev, bh->b_dev);
clear_bit(BH_Uptodate, &bh->b_state);
}
clear_bit(BH_Lock, &bh->b_state);
@@ -440,7 +440,7 @@
md_spin_lock_irqsave(&conf->device_lock, flags);
if (!uptodate)
- md_error(mddev_to_kdev(conf->mddev), bh->b_dev);
+ md_error(conf->mddev, bh->b_dev);
clear_bit(BH_Lock, &bh->b_state);
set_bit(STRIPE_HANDLE, &sh->state);
__release_stripe(conf, sh);
@@ -886,7 +886,7 @@
}
}
if (syncing) {
- md_done_sync(conf->mddev, (sh->size>>10) - sh->sync_redone,0);
+ md_done_sync(conf->mddev, (sh->size>>9) - sh->sync_redone,0);
clear_bit(STRIPE_SYNCING, &sh->state);
syncing = 0;
}
@@ -1051,15 +1051,15 @@
action[failed_num] = WRITE+1;
locked++;
set_bit(STRIPE_INSYNC, &sh->state);
- if (conf->disks[i].operational)
- md_sync_acct(conf->disks[i].dev, bh->b_size>>9);
+ if (conf->disks[failed_num].operational)
+ md_sync_acct(conf->disks[failed_num].dev, bh->b_size>>9);
else if (conf->spare)
md_sync_acct(conf->spare->dev, bh->b_size>>9);
}
}
if (syncing && locked == 0 && test_bit(STRIPE_INSYNC, &sh->state)) {
- md_done_sync(conf->mddev, (sh->size>>10) - sh->sync_redone,1);
+ md_done_sync(conf->mddev, (sh->size>>9) - sh->sync_redone,1);
clear_bit(STRIPE_SYNCING, &sh->state);
}
@@ -1153,13 +1153,13 @@
return correct_size;
}
-static int raid5_sync_request (mddev_t *mddev, unsigned long block_nr)
+static int raid5_sync_request (mddev_t *mddev, unsigned long sector_nr)
{
raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
struct stripe_head *sh;
int sectors_per_chunk = conf->chunk_size >> 9;
- unsigned long stripe = (block_nr<<1)/sectors_per_chunk;
- int chunk_offset = (block_nr<<1) % sectors_per_chunk;
+ unsigned long stripe = sector_nr/sectors_per_chunk;
+ int chunk_offset = sector_nr % sectors_per_chunk;
int dd_idx, pd_idx;
unsigned long first_sector;
int raid_disks = conf->raid_disks;
@@ -1167,9 +1167,9 @@
int redone = 0;
int bufsize;
- sh = get_active_stripe(conf, block_nr<<1, 0, 0);
+ sh = get_active_stripe(conf, sector_nr, 0, 0);
bufsize = sh->size;
- redone = block_nr-(sh->sector>>1);
+ redone = sector_nr - sh->sector;
first_sector = raid5_compute_sector(stripe*data_disks*sectors_per_chunk
+ chunk_offset, raid_disks, data_disks, &dd_idx, &pd_idx, conf);
sh->pd_idx = pd_idx;
@@ -1182,7 +1182,7 @@
handle_stripe(sh);
release_stripe(sh);
- return (bufsize>>10)-redone;
+ return (bufsize>>9)-redone;
}
/*
@@ -1256,76 +1256,6 @@
printk("raid5: resync finished.\n");
}
-static int __check_consistency (mddev_t *mddev, int row)
-{
- raid5_conf_t *conf = mddev->private;
- kdev_t dev;
- struct buffer_head *bh[MD_SB_DISKS], *tmp = NULL;
- int i, ret = 0, nr = 0, count;
- struct buffer_head *bh_ptr[MAX_XOR_BLOCKS];
-
- if (conf->working_disks != conf->raid_disks)
- goto out;
- tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
- tmp->b_size = 4096;
- tmp->b_page = alloc_page(GFP_KERNEL);
- tmp->b_data = page_address(tmp->b_page);
- if (!tmp->b_data)
- goto out;
- md_clear_page(tmp->b_data);
- memset(bh, 0, MD_SB_DISKS * sizeof(struct buffer_head *));
- for (i = 0; i < conf->raid_disks; i++) {
- dev = conf->disks[i].dev;
- set_blocksize(dev, 4096);
- bh[i] = bread(dev, row / 4, 4096);
- if (!bh[i])
- break;
- nr++;
- }
- if (nr == conf->raid_disks) {
- bh_ptr[0] = tmp;
- count = 1;
- for (i = 1; i < nr; i++) {
- bh_ptr[count++] = bh[i];
- if (count == MAX_XOR_BLOCKS) {
- xor_block(count, &bh_ptr[0]);
- count = 1;
- }
- }
- if (count != 1) {
- xor_block(count, &bh_ptr[0]);
- }
- if (memcmp(tmp->b_data, bh[0]->b_data, 4096))
- ret = 1;
- }
- for (i = 0; i < conf->raid_disks; i++) {
- dev = conf->disks[i].dev;
- if (bh[i]) {
- bforget(bh[i]);
- bh[i] = NULL;
- }
- fsync_dev(dev);
- invalidate_buffers(dev);
- }
- free_page((unsigned long) tmp->b_data);
-out:
- if (tmp)
- kfree(tmp);
- return ret;
-}
-
-static int check_consistency (mddev_t *mddev)
-{
- if (__check_consistency(mddev, 0))
-/*
- * We are not checking this currently, as it's legitimate to have
- * an inconsistent array, at creation time.
- */
- return 0;
-
- return 0;
-}
-
static int raid5_run (mddev_t *mddev)
{
raid5_conf_t *conf;
@@ -1485,12 +1415,6 @@
start_recovery = 1;
}
- if (!start_recovery && (sb->state & (1 << MD_SB_CLEAN)) &&
- check_consistency(mddev)) {
- printk(KERN_ERR "raid5: detected raid-5 superblock xor inconsistency -- running resync\n");
- sb->state &= ~(1 << MD_SB_CLEAN);
- }
-
{
const char * name = "raid5d";
@@ -1704,6 +1628,7 @@
struct disk_info *tmp, *sdisk, *fdisk, *rdisk, *adisk;
mdp_super_t *sb = mddev->sb;
mdp_disk_t *failed_desc, *spare_desc, *added_desc;
+ mdk_rdev_t *spare_rdev, *failed_rdev;
print_raid5_conf(conf);
md_spin_lock_irq(&conf->device_lock);
@@ -1875,6 +1800,16 @@
/*
* do the switch finally
*/
+ spare_rdev = find_rdev_nr(mddev, spare_desc->number);
+ failed_rdev = find_rdev_nr(mddev, failed_desc->number);
+
+ /* There must be a spare_rdev, but there may not be a
+ * failed_rdev. That slot might be empty...
+ */
+ spare_rdev->desc_nr = failed_desc->number;
+ if (failed_rdev)
+ failed_rdev->desc_nr = spare_desc->number;
+
xchg_values(*spare_desc, *failed_desc);
xchg_values(*fdisk, *sdisk);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)