Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 38118
b: refs/heads/master
c: 867868f
h: refs/heads/master
v: v3
  • Loading branch information
NeilBrown authored and Linus Torvalds committed Oct 3, 2006
1 parent 67581be commit 0aa4007
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 79 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2d2063ceae73660d5142f4754d50a75b655fd1f9
refs/heads/master: 867868fb557eb2a2120b80779468fa372584ddb0
173 changes: 95 additions & 78 deletions trunk/drivers/md/raid1.c
Original file line number Diff line number Diff line change
Expand Up @@ -1368,6 +1368,95 @@ static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
* 3. Performs writes following reads for array syncronising.
*/

static void fix_read_error(conf_t *conf, int read_disk,
sector_t sect, int sectors)
{
mddev_t *mddev = conf->mddev;
while(sectors) {
int s = sectors;
int d = read_disk;
int success = 0;
int start;
mdk_rdev_t *rdev;

if (s > (PAGE_SIZE>>9))
s = PAGE_SIZE >> 9;

do {
/* Note: no rcu protection needed here
* as this is synchronous in the raid1d thread
* which is the thread that might remove
* a device. If raid1d ever becomes multi-threaded....
*/
rdev = conf->mirrors[d].rdev;
if (rdev &&
test_bit(In_sync, &rdev->flags) &&
sync_page_io(rdev->bdev,
sect + rdev->data_offset,
s<<9,
conf->tmppage, READ))
success = 1;
else {
d++;
if (d == conf->raid_disks)
d = 0;
}
} while (!success && d != read_disk);

if (!success) {
/* Cannot read from anywhere -- bye bye array */
md_error(mddev, conf->mirrors[read_disk].rdev);
break;
}
/* write it back and re-read */
start = d;
while (d != read_disk) {
if (d==0)
d = conf->raid_disks;
d--;
rdev = conf->mirrors[d].rdev;
if (rdev &&
test_bit(In_sync, &rdev->flags)) {
if (sync_page_io(rdev->bdev,
sect + rdev->data_offset,
s<<9, conf->tmppage, WRITE)
== 0)
/* Well, this device is dead */
md_error(mddev, rdev);
}
}
d = start;
while (d != read_disk) {
char b[BDEVNAME_SIZE];
if (d==0)
d = conf->raid_disks;
d--;
rdev = conf->mirrors[d].rdev;
if (rdev &&
test_bit(In_sync, &rdev->flags)) {
if (sync_page_io(rdev->bdev,
sect + rdev->data_offset,
s<<9, conf->tmppage, READ)
== 0)
/* Well, this device is dead */
md_error(mddev, rdev);
else {
atomic_add(s, &rdev->corrected_errors);
printk(KERN_INFO
"raid1:%s: read error corrected "
"(%d sectors at %llu on %s)\n",
mdname(mddev), s,
(unsigned long long)sect +
rdev->data_offset,
bdevname(rdev->bdev, b));
}
}
}
sectors -= s;
sect += s;
}
}

static void raid1d(mddev_t *mddev)
{
r1bio_t *r1_bio;
Expand Down Expand Up @@ -1460,86 +1549,14 @@ static void raid1d(mddev_t *mddev)
* This is all done synchronously while the array is
* frozen
*/
sector_t sect = r1_bio->sector;
int sectors = r1_bio->sectors;
freeze_array(conf);
if (mddev->ro == 0) while(sectors) {
int s = sectors;
int d = r1_bio->read_disk;
int success = 0;

if (s > (PAGE_SIZE>>9))
s = PAGE_SIZE >> 9;

do {
/* Note: no rcu protection needed here
* as this is synchronous in the raid1d thread
* which is the thread that might remove
* a device. If raid1d ever becomes multi-threaded....
*/
rdev = conf->mirrors[d].rdev;
if (rdev &&
test_bit(In_sync, &rdev->flags) &&
sync_page_io(rdev->bdev,
sect + rdev->data_offset,
s<<9,
conf->tmppage, READ))
success = 1;
else {
d++;
if (d == conf->raid_disks)
d = 0;
}
} while (!success && d != r1_bio->read_disk);

if (success) {
/* write it back and re-read */
int start = d;
while (d != r1_bio->read_disk) {
if (d==0)
d = conf->raid_disks;
d--;
rdev = conf->mirrors[d].rdev;
if (rdev &&
test_bit(In_sync, &rdev->flags)) {
if (sync_page_io(rdev->bdev,
sect + rdev->data_offset,
s<<9, conf->tmppage, WRITE) == 0)
/* Well, this device is dead */
md_error(mddev, rdev);
}
}
d = start;
while (d != r1_bio->read_disk) {
if (d==0)
d = conf->raid_disks;
d--;
rdev = conf->mirrors[d].rdev;
if (rdev &&
test_bit(In_sync, &rdev->flags)) {
if (sync_page_io(rdev->bdev,
sect + rdev->data_offset,
s<<9, conf->tmppage, READ) == 0)
/* Well, this device is dead */
md_error(mddev, rdev);
else {
atomic_add(s, &rdev->corrected_errors);
printk(KERN_INFO "raid1:%s: read error corrected (%d sectors at %llu on %s)\n",
mdname(mddev), s, (unsigned long long)(sect + rdev->data_offset), bdevname(rdev->bdev, b));
}
}
}
} else {
/* Cannot read from anywhere -- bye bye array */
md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev);
break;
}
sectors -= s;
sect += s;
if (mddev->ro == 0) {
freeze_array(conf);
fix_read_error(conf, r1_bio->read_disk,
r1_bio->sector,
r1_bio->sectors);
unfreeze_array(conf);
}

unfreeze_array(conf);

bio = r1_bio->bios[r1_bio->read_disk];
if ((disk=read_balance(conf, r1_bio)) == -1) {
printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
Expand Down

0 comments on commit 0aa4007

Please sign in to comment.