This is a combined patch of Martin changes and mine.
It does appear to keep the raid5 code a bit happier, and clue
us in on the results.
--
Russell Cattelan
--
Digital Elves inc. -- Currently on loan to SGI
Linux XFS core developer.
===========================================================================
Index: linux/drivers/md/md.c
===========================================================================
--- /usr/tmp/TmpDir.3925-0/linux/drivers/md/md.c_1.6 Thu Feb 15 21:45:48 2001
+++ linux/drivers/md/md.c Thu Feb 15 13:46:59 2001
@@ -2033,65 +2033,69 @@
struct {
int set;
int noautodetect;
-} raid_setup_args md__initdata;
-void md_setup_drive (void) md__init;
+} raid_setup_args md__initdata = { 0, 0 };
+
+void md_setup_drive(void) md__init;
/*
* Searches all registered partitions for autorun RAID arrays
* at boot time.
*/
-static int detected_devices[128] md__initdata;
-static int dev_cnt;
-
+#define CONFIG_AUTODETECT_RAID
+#ifdef CONFIG_AUTODETECT_RAID
+static int detected_devices[128] md__initdata = { 0, };
+static int dev_cnt=0;
void md_autodetect_dev(kdev_t dev)
{
if (dev_cnt >= 0 && dev_cnt < 127)
detected_devices[dev_cnt++] = dev;
}
+#endif
-
-static void autostart_arrays (void)
+int md__init md_run_setup(void)
{
+#ifdef CONFIG_AUTODETECT_RAID
mdk_rdev_t *rdev;
int i;
- printk(KERN_INFO "autodetecting RAID arrays\n");
+ if (raid_setup_args.noautodetect)
+ printk(KERN_INFO "skipping autodetection of RAID arrays\n");
+ else {
- for (i=0; i<dev_cnt; i++) {
- kdev_t dev = detected_devices[i];
+ printk(KERN_INFO "autodetecting RAID arrays\n");
- if (md_import_device(dev,1)) {
- printk(KERN_ALERT "could not import %s!\n",
- partition_name(dev));
- continue;
- }
- /*
- * Sanity checks:
- */
- rdev = find_rdev_all(dev);
- if (!rdev) {
- MD_BUG();
- continue;
- }
- if (rdev->faulty) {
- MD_BUG();
- continue;
+ for (i=0; i<dev_cnt; i++) {
+ kdev_t dev = detected_devices[i];
+
+ if (md_import_device(dev,1)) {
+ printk(KERN_ALERT "could not import %s!\n",
+ partition_name(dev));
+ continue;
+ }
+ /*
+ * Sanity checks:
+ */
+ rdev = find_rdev_all(dev);
+ if (!rdev) {
+ MD_BUG();
+ continue;
+ }
+ if (rdev->faulty) {
+ MD_BUG();
+ continue;
+ }
+ md_list_add(&rdev->pending, &pending_raid_disks);
}
- md_list_add(&rdev->pending, &pending_raid_disks);
- }
- autorun_devices(-1);
-}
+ autorun_devices(-1);
+ }
-int md__init md_run_setup(void)
-{
- if (raid_setup_args.noautodetect)
- printk(KERN_INFO "skipping autodetection of RAID arrays\n");
- else
- autostart_arrays();
dev_cnt = -1; /* make sure further calls to md_autodetect_dev are
ignored */
+#endif
+#ifdef CONFIG_MD_BOOT
md_setup_drive();
+#endif
return 0;
}
@@ -2555,11 +2559,6 @@
md_print_devices();
goto done_unlock;
- case RAID_AUTORUN:
- err = 0;
- autostart_arrays();
- goto done;
-
case BLKGETSIZE: /* Return device size */
if (!arg) {
err = -EINVAL;
@@ -2713,6 +2712,7 @@
case BLKSETSIZE:
set_blocksize (mddev, (int *) arg);
goto done_unlock;
+
/*
* We have a problem here : there is no easy way to give a CHS
@@ -3056,9 +3056,11 @@
int sz = 0;
unsigned long max_blocks, resync, res, dt, db, rt;
- resync = mddev->curr_resync - atomic_read(&mddev->recovery_active);
+ resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active)) >>
1;
max_blocks = mddev->sb->size;
+ printk ("Res: %ld, Max Blocks: %ld\n", resync, max_blocks);
+
/*
* Should not happen.
*/
@@ -3103,7 +3105,7 @@
if (!dt) dt++;
db = resync - mddev->resync_mark_cnt;
rt = (dt * ((max_blocks-resync) / (db/100+1)))/100;
-
+
sz += sprintf(page + sz, " finish=%lu.%lumin", rt / 60, (rt % 60)/6);
sz += sprintf(page + sz, " speed=%ldK/sec", db/dt);
@@ -3274,10 +3276,10 @@
MD_DECLARE_WAIT_QUEUE_HEAD(resync_wait);
-void md_done_sync(mddev_t *mddev, int blocks, int ok)
+void md_done_sync(mddev_t *mddev, int sectors, int ok)
{
- /* another "blocks" (1K) blocks have been synced */
- atomic_sub(blocks, &mddev->recovery_active);
+ /* another chunk of sectors has been synced */
+ atomic_sub(sectors, &mddev->recovery_active);
wake_up(&mddev->recovery_wait);
if (!ok) {
// stop recovery, signal do_sync ....
@@ -3289,7 +3291,7 @@
int md_do_sync(mddev_t *mddev, mdp_disk_t *spare)
{
mddev_t *mddev2;
- unsigned int max_blocks, currspeed,
+ unsigned int max_sectors, currspeed,
j, window, err, serialize;
kdev_t read_disk = mddev_to_kdev(mddev);
unsigned long mark[SYNC_MARKS];
@@ -3326,7 +3328,7 @@
mddev->curr_resync = 1;
- max_blocks = mddev->sb->size;
+ max_sectors = mddev->sb->size << 1;
printk(KERN_INFO "md: syncing RAID array md%d\n", mdidx(mddev));
printk(KERN_INFO "md: minimum _guaranteed_ reconstruction speed: %d
KB/sec/disc.\n",
@@ -3351,22 +3353,22 @@
* Tune reconstruction:
*/
window = MAX_READAHEAD*(PAGE_SIZE/1024);
- printk(KERN_INFO "md: using %dk window, over a total of %d
blocks.\n",window,max_blocks);
+ printk(KERN_INFO "md: using %dk window, over a total of %d
sectors.\n",window, max_sectors);
atomic_set(&mddev->recovery_active, 0);
init_waitqueue_head(&mddev->recovery_wait);
last_check = 0;
- for (j = 0; j < max_blocks;) {
- int blocks;
+ for (j = 0; j < max_sectors;) {
+ int sectors;
- blocks = mddev->pers->sync_request(mddev, j);
+ sectors = mddev->pers->sync_request(mddev, j);
- if (blocks < 0) {
- err = blocks;
+ if (sectors < 0) {
+ err = sectors;
goto out;
}
- atomic_add(blocks, &mddev->recovery_active);
- j += blocks;
+ atomic_add(sectors, &mddev->recovery_active);
+ j += sectors;
mddev->curr_resync = j;
if (last_check + window > j)
@@ -3384,7 +3386,7 @@
mark_cnt[next] = j -
atomic_read(&mddev->recovery_active);
last_mark = next;
}
-
+
if (md_signal_pending(current)) {
/*
@@ -3626,7 +3628,7 @@
&md_fops, NULL);
/* forward all md request to md_make_request */
- blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), md_make_request);
+ blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR), (void *)
md_make_request);
read_ahead[MAJOR_NR] = INT_MAX;
@@ -3645,12 +3647,14 @@
return (0);
}
-static struct {
- char device_set [MAX_MD_DEVS];
- int pers[MAX_MD_DEVS];
- int chunk[MAX_MD_DEVS];
- kdev_t devices[MAX_MD_DEVS][MD_SB_DISKS];
-} md_setup_args md__initdata;
+#ifdef CONFIG_MD_BOOT
+#define MAX_MD_BOOT_DEVS 8
+struct {
+ unsigned long set;
+ int pers[MAX_MD_BOOT_DEVS];
+ int chunk[MAX_MD_BOOT_DEVS];
+ kdev_t devices[MAX_MD_BOOT_DEVS][MD_SB_DISKS];
+} md_setup_args md__initdata = { 0, };
/*
* Parse the command-line parameters given our kernel, but do not
@@ -3680,10 +3684,10 @@
printk("md: Too few arguments supplied to md=.\n");
return 0;
}
- if (minor >= MAX_MD_DEVS) {
+ if (minor >= MAX_MD_BOOT_DEVS) {
printk ("md: Minor device number too high.\n");
return 0;
- } else if (md_setup_args.device_set[minor]) {
+ } else if (md_setup_args.set & (1 << minor)) {
printk ("md: Warning - md=%d,... has been specified twice;\n"
" will discard the first definition.\n", minor);
}
@@ -3741,7 +3745,7 @@
printk ("md: Will configure md%d (%s) from %s, below.\n",
minor, pername, devnames);
md_setup_args.devices[minor][i] = (kdev_t) 0;
- md_setup_args.device_set[minor] = 1;
+ md_setup_args.set |= (1 << minor);
return 1;
}
@@ -3751,11 +3755,10 @@
kdev_t dev;
mddev_t*mddev;
- for (minor = 0; minor < MAX_MD_DEVS; minor++) {
+ for (minor = 0; minor < MAX_MD_BOOT_DEVS; minor++) {
mdu_disk_info_t dinfo;
-
- int err = 0;
- if (!md_setup_args.device_set[minor])
+ int err=0;
+ if (!(md_setup_args.set & (1 << minor)))
continue;
printk("md: Loading md%d.\n", minor);
if (mddev_map[minor].mddev) {
@@ -3781,7 +3784,7 @@
ainfo.layout = 0;
ainfo.chunk_size = md_setup_args.chunk[minor];
err = set_array_info(mddev, &ainfo);
- for (i = 0; !err && (dev =
md_setup_args.devices[minor][i]); i++) {
+ for (i=0; !err && (dev =
md_setup_args.devices[minor][i]); i++) {
dinfo.number = i;
dinfo.raid_disk = i;
dinfo.state =
(1<<MD_DISK_ACTIVE)|(1<<MD_DISK_SYNC);
@@ -3812,6 +3815,7 @@
}
__setup("md=", md_setup);
+#endif
#ifdef MODULE
int init_module (void)
@@ -3863,7 +3867,9 @@
#endif
__initcall(md_init);
+#if defined(CONFIG_AUTODETECT_RAID) || defined(CONFIG_MD_BOOT)
__initcall(md_run_setup);
+#endif
MD_EXPORT_SYMBOL(md_size);
MD_EXPORT_SYMBOL(register_md_personality);
===========================================================================
Index: linux/drivers/md/raid5.c
===========================================================================
--- /usr/tmp/TmpDir.3925-0/linux/drivers/md/raid5.c_1.8 Thu Feb 15 21:45:48 2001
+++ linux/drivers/md/raid5.c Thu Feb 15 20:43:09 2001
@@ -272,6 +272,7 @@
if (conf->buffer_size != size) {
printk("raid5: switching cache buffer
size, %d --> %d\n", oldsize, size);
+ printk("raid5: conf->buffer_size =
%d\n", conf->buffer_size);
shrink_stripe_cache(conf);
if (size==0) BUG();
conf->buffer_size = size;
@@ -714,16 +715,19 @@
break;
}
spin_unlock_irq(&conf->device_lock);
- if (count>1) {
- xor_block(count, bh_ptr);
- count = 1;
- }
-
+ if (count>1) {
+ xor_block(count, bh_ptr);
+ count = 1;
+ }
for (i = disks; i--;)
if (chosen[i]) {
struct buffer_head *bh = sh->bh_cache[i];
char *bdata;
- mark_buffer_clean(chosen[i]); /* NO FIXME */
+ if(!(test_bit(BH_End_io, &(chosen[i]->b_state))
+ || chosen[i]->b_next_free == NULL
+ || chosen[i]->b_prev_free == NULL )){
+ mark_buffer_clean(chosen[i]);
+ }
bdata = bh_kmap(chosen[i]);
memcpy(bh->b_data,
bdata,sh->size);
@@ -888,7 +892,7 @@
}
spin_unlock_irq(&conf->device_lock);
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;
}
@@ -1063,7 +1067,7 @@
}
}
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);
}
@@ -1159,13 +1163,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)
{
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/sectors_per_chunk;
+ int chunk_offset = sector % sectors_per_chunk;
int dd_idx, pd_idx;
unsigned long first_sector;
int raid_disks = conf->raid_disks;
@@ -1173,9 +1177,9 @@
int redone = 0;
int bufsize;
- sh = get_active_stripe(conf, block_nr<<1, 0, 0);
+ sh = get_active_stripe(conf, sector, 0, 0);
bufsize = sh->size;
- redone = block_nr-(sh->sector>>1);
+ redone = sector - 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;
@@ -1188,7 +1192,7 @@
handle_stripe(sh);
release_stripe(sh);
- return (bufsize>>10)-redone;
+ return (bufsize >> 9) - redone;
}
/*
|