patch-2.4.0-test12 linux/drivers/md/raid1.c
Next file: linux/drivers/md/raid5.c
Previous file: linux/drivers/md/raid0.c
Back to the patch index
Back to the overall index
- Lines: 308
- Date:
Mon Dec 11 13:19:35 2000
- Orig file:
v2.4.0-test11/linux/drivers/md/raid1.c
- Orig date:
Sun Nov 19 18:44:08 2000
diff -u --recursive --new-file v2.4.0-test11/linux/drivers/md/raid1.c linux/drivers/md/raid1.c
@@ -463,16 +463,12 @@
if (conf->resync_mirrors)
goto rb_out;
- if (conf->working_disks < 2) {
- int i = 0;
-
- while( !conf->mirrors[new_disk].operational &&
- (i < MD_SB_DISKS) ) {
- new_disk = conf->mirrors[new_disk].next;
- i++;
- }
-
- if (i >= MD_SB_DISKS) {
+
+ /* make sure that disk is operational */
+ while( !conf->mirrors[new_disk].operational) {
+ if (new_disk <= 0) new_disk = conf->raid_disks;
+ new_disk--;
+ if (new_disk == disk) {
/*
* This means no working disk was found
* Nothing much to do, lets not change anything
@@ -480,11 +476,13 @@
*/
new_disk = conf->last_used;
+
+ goto rb_out;
}
-
- goto rb_out;
}
-
+ disk = new_disk;
+ /* now disk == new_disk == starting point for search */
+
/*
* Don't touch anything for sequential reads.
*/
@@ -501,16 +499,16 @@
if (conf->sect_count >= conf->mirrors[new_disk].sect_limit) {
conf->sect_count = 0;
-
- while( new_disk != conf->mirrors[new_disk].next ) {
- if ((conf->mirrors[new_disk].write_only) ||
- (!conf->mirrors[new_disk].operational) )
- continue;
-
- new_disk = conf->mirrors[new_disk].next;
- break;
- }
-
+
+ do {
+ if (new_disk<=0)
+ new_disk = conf->raid_disks;
+ new_disk--;
+ if (new_disk == disk)
+ break;
+ } while ((conf->mirrors[new_disk].write_only) ||
+ (!conf->mirrors[new_disk].operational));
+
goto rb_out;
}
@@ -519,8 +517,10 @@
/* Find the disk which is closest */
- while( conf->mirrors[disk].next != conf->last_used ) {
- disk = conf->mirrors[disk].next;
+ do {
+ if (disk <= 0)
+ disk = conf->raid_disks;
+ disk--;
if ((conf->mirrors[disk].write_only) ||
(!conf->mirrors[disk].operational))
@@ -534,7 +534,7 @@
current_distance = new_distance;
new_disk = disk;
}
- }
+ } while (disk != conf->last_used);
rb_out:
conf->mirrors[new_disk].head_position = this_sector + sectors;
@@ -702,16 +702,6 @@
return sz;
}
-static void unlink_disk (raid1_conf_t *conf, int target)
-{
- int disks = MD_SB_DISKS;
- int i;
-
- for (i = 0; i < disks; i++)
- if (conf->mirrors[i].next == target)
- conf->mirrors[i].next = conf->mirrors[target].next;
-}
-
#define LAST_DISK KERN_ALERT \
"raid1: only one disk left and IO error.\n"
@@ -735,7 +725,6 @@
mdp_super_t *sb = mddev->sb;
mirror->operational = 0;
- unlink_disk(conf, failed);
mark_disk_faulty(sb->disks+mirror->number);
mark_disk_nonsync(sb->disks+mirror->number);
mark_disk_inactive(sb->disks+mirror->number);
@@ -786,25 +775,6 @@
#undef DISK_FAILED
#undef START_SYNCING
-/*
- * Insert the spare disk into the drive-ring
- */
-static void link_disk(raid1_conf_t *conf, struct mirror_info *mirror)
-{
- int j, next;
- int disks = MD_SB_DISKS;
- struct mirror_info *p = conf->mirrors;
-
- for (j = 0; j < disks; j++, p++)
- if (p->operational && !p->write_only) {
- next = p->next;
- p->next = mirror->raid_disk;
- mirror->next = next;
- return;
- }
-
- printk("raid1: bug: no read-operational devices\n");
-}
static void print_raid1_conf (raid1_conf_t *conf)
{
@@ -828,6 +798,32 @@
}
}
+static void close_sync(raid1_conf_t *conf)
+{
+ mddev_t *mddev = conf->mddev;
+ /* If reconstruction was interrupted, we need to close the "active" and "pending"
+ * holes.
+ * we know that there are no active rebuild requests, os cnt_active == cnt_ready ==0
+ */
+ /* this is really needed when recovery stops too... */
+ spin_lock_irq(&conf->segment_lock);
+ conf->start_active = conf->start_pending;
+ conf->start_ready = conf->start_pending;
+ wait_event_lock_irq(conf->wait_ready, !conf->cnt_pending, conf->segment_lock);
+ conf->start_active =conf->start_ready = conf->start_pending = conf->start_future;
+ conf->start_future = mddev->sb->size+1;
+ conf->cnt_pending = conf->cnt_future;
+ conf->cnt_future = 0;
+ conf->phase = conf->phase ^1;
+ wait_event_lock_irq(conf->wait_ready, !conf->cnt_pending, conf->segment_lock);
+ conf->start_active = conf->start_ready = conf->start_pending = conf->start_future = 0;
+ conf->phase = 0;
+ conf->cnt_future = conf->cnt_done;;
+ conf->cnt_done = 0;
+ spin_unlock_irq(&conf->segment_lock);
+ wake_up(&conf->wait_done);
+}
+
static int raid1_diskop(mddev_t *mddev, mdp_disk_t **d, int state)
{
int err = 0;
@@ -940,6 +936,7 @@
* Deactivate a spare disk:
*/
case DISKOP_SPARE_INACTIVE:
+ close_sync(conf);
sdisk = conf->mirrors + spare_disk;
sdisk->operational = 0;
sdisk->write_only = 0;
@@ -952,7 +949,7 @@
* property)
*/
case DISKOP_SPARE_ACTIVE:
-
+ close_sync(conf);
sdisk = conf->mirrors + spare_disk;
fdisk = conf->mirrors + failed_disk;
@@ -1017,7 +1014,6 @@
*/
fdisk->spare = 0;
fdisk->write_only = 0;
- link_disk(conf, fdisk);
/*
* if we activate a spare, we definitely replace a
@@ -1244,27 +1240,7 @@
conf->resync_mirrors = 0;
}
- /* If reconstruction was interrupted, we need to close the "active" and "pending"
- * holes.
- * we know that there are no active rebuild requests, os cnt_active == cnt_ready ==0
- */
- /* this is really needed when recovery stops too... */
- spin_lock_irq(&conf->segment_lock);
- conf->start_active = conf->start_pending;
- conf->start_ready = conf->start_pending;
- wait_event_lock_irq(conf->wait_ready, !conf->cnt_pending, conf->segment_lock);
- conf->start_active =conf->start_ready = conf->start_pending = conf->start_future;
- conf->start_future = mddev->sb->size+1;
- conf->cnt_pending = conf->cnt_future;
- conf->cnt_future = 0;
- conf->phase = conf->phase ^1;
- wait_event_lock_irq(conf->wait_ready, !conf->cnt_pending, conf->segment_lock);
- conf->start_active = conf->start_ready = conf->start_pending = conf->start_future = 0;
- conf->phase = 0;
- conf->cnt_future = conf->cnt_done;;
- conf->cnt_done = 0;
- spin_unlock_irq(&conf->segment_lock);
- wake_up(&conf->wait_done);
+ close_sync(conf);
up(&mddev->recovery_sem);
raid1_shrink_buffers(conf);
@@ -1325,6 +1301,7 @@
struct raid1_bh *r1_bh;
struct buffer_head *bh;
int bsize;
+ int disk;
spin_lock_irq(&conf->segment_lock);
if (!block_nr) {
@@ -1377,6 +1354,16 @@
* could dedicate one to rebuild and others to
* service read requests ..
*/
+ disk = conf->last_used;
+ /* make sure disk is operational */
+ while (!conf->mirrors[disk].operational) {
+ if (disk <= 0) disk = conf->raid_disks;
+ disk--;
+ if (disk == conf->last_used)
+ break;
+ }
+ conf->last_used = disk;
+
mirror = conf->mirrors+conf->last_used;
r1_bh = raid1_alloc_buf (conf);
@@ -1396,7 +1383,7 @@
bh->b_list = BUF_LOCKED;
bh->b_dev = mirror->dev;
bh->b_rdev = mirror->dev;
- bh->b_state = (1<<BH_Req) | (1<<BH_Mapped);
+ bh->b_state = (1<<BH_Req) | (1<<BH_Mapped) | (1<<BH_Lock);
if (!bh->b_page)
BUG();
if (!bh->b_data)
@@ -1717,19 +1704,10 @@
* find the first working one and use it as a starting point
* to read balancing.
*/
- for (j = 0; !conf->mirrors[j].operational; j++)
+ for (j = 0; !conf->mirrors[j].operational && j < MD_SB_DISKS; j++)
/* nothing */;
conf->last_used = j;
- /*
- * initialize the 'working disks' list.
- */
- for (i = conf->raid_disks - 1; i >= 0; i--) {
- if (conf->mirrors[i].operational) {
- conf->mirrors[i].next = j;
- j = i;
- }
- }
if (conf->working_disks != sb->raid_disks) {
printk(KERN_ALERT "raid1: md%d, not all disks are operational -- trying to recover array\n", mdidx(mddev));
@@ -1882,19 +1860,16 @@
sync_request: raid1_sync_request
};
-int raid1_init (void)
+static int md__init raid1_init (void)
{
return register_md_personality (RAID1, &raid1_personality);
}
-#ifdef MODULE
-int init_module (void)
-{
- return raid1_init();
-}
-
-void cleanup_module (void)
+static void raid1_exit (void)
{
unregister_md_personality (RAID1);
}
-#endif
+
+module_init(raid1_init);
+module_exit(raid1_exit);
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)