[prev in list] [next in list] [prev in thread] [next in thread]
List: linux-raid
Subject: [PATCH] raid1 to use sector numbers in b_blocknr
From: Neil Brown <neilb () cse ! unsw ! edu ! au>
Date: 2001-05-24 1:16:38
[Download RAW message or body]
Linus,
raid1 allocates a new buffer_head when passing a request done
to an underlying device.
It currently sets b_blocknr to b_rsector/(b_size>>9) from the
original buffer_head to parallel other uses of b_blocknr (i.e. it
being the number of the block).
However, if raid1 gets a non-aligned request, then the calcuation of
b_blocknr would loose information resulting in potential data
curruption if the request were resubmitted to a different drive on
failure.
Non aligned requests aren't currently possible (I believe) but newer
filesystems are ikely to want them soon, and if a raid1 array were
to be partitioned into partitions that were not page aligned, it
could happen.
This patch changes the usage of b_blocknr in raid1.c to store the
value of b_rsector of the incoming request.
Also, I remove the third argument to raid1_map which is never used.
NeilBrown
--- ./drivers/md/raid1.c 2001/05/23 01:18:15 1.1
+++ ./drivers/md/raid1.c 2001/05/23 01:18:19 1.2
@@ -298,7 +298,7 @@
md_spin_unlock_irq(&conf->device_lock);
}
-static int raid1_map (mddev_t *mddev, kdev_t *rdev, unsigned long size)
+static int raid1_map (mddev_t *mddev, kdev_t *rdev)
{
raid1_conf_t *conf = mddev_to_conf(mddev);
int i, disks = MD_SB_DISKS;
@@ -602,7 +602,7 @@
bh_req = &r1_bh->bh_req;
memcpy(bh_req, bh, sizeof(*bh));
- bh_req->b_blocknr = bh->b_rsector / sectors;
+ bh_req->b_blocknr = bh->b_rsector;
bh_req->b_dev = mirror->dev;
bh_req->b_rdev = mirror->dev;
/* bh_req->b_rsector = bh->n_rsector; */
@@ -646,7 +646,7 @@
/*
* prepare mirrored mbh (fields ordered for max mem throughput):
*/
- mbh->b_blocknr = bh->b_rsector / sectors;
+ mbh->b_blocknr = bh->b_rsector;
mbh->b_dev = conf->mirrors[i].dev;
mbh->b_rdev = conf->mirrors[i].dev;
mbh->b_rsector = bh->b_rsector;
@@ -1138,7 +1138,6 @@
int disks = MD_SB_DISKS;
struct buffer_head *bhl, *mbh;
raid1_conf_t *conf;
- int sectors = bh->b_size >> 9;
conf = mddev_to_conf(mddev);
bhl = raid1_alloc_bh(conf, conf->raid_disks); /* don't really need this many */
@@ -1168,7 +1167,7 @@
mbh->b_blocknr = bh->b_blocknr;
mbh->b_dev = conf->mirrors[i].dev;
mbh->b_rdev = conf->mirrors[i].dev;
- mbh->b_rsector = bh->b_blocknr * sectors;
+ mbh->b_rsector = bh->b_blocknr;
mbh->b_state = (1<<BH_Req) | (1<<BH_Dirty) |
(1<<BH_Mapped) | (1<<BH_Lock);
atomic_set(&mbh->b_count, 1);
@@ -1195,7 +1194,7 @@
}
} else {
dev = bh->b_dev;
- raid1_map (mddev, &bh->b_dev, bh->b_size >> 9);
+ raid1_map (mddev, &bh->b_dev);
if (bh->b_dev == dev) {
printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr);
md_done_sync(mddev, bh->b_size>>9, 0);
@@ -1203,6 +1202,7 @@
printk (REDIRECT_SECTOR,
partition_name(bh->b_dev), bh->b_blocknr);
bh->b_rdev = bh->b_dev;
+ bh->b_rsector = bh->b_blocknr;
generic_make_request(READ, bh);
}
}
@@ -1211,8 +1211,7 @@
case READ:
case READA:
dev = bh->b_dev;
-
- raid1_map (mddev, &bh->b_dev, bh->b_size >> 9);
+ raid1_map (mddev, &bh->b_dev);
if (bh->b_dev == dev) {
printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr);
raid1_end_bh_io(r1_bh, 0);
@@ -1220,6 +1219,7 @@
printk (REDIRECT_SECTOR,
partition_name(bh->b_dev), bh->b_blocknr);
bh->b_rdev = bh->b_dev;
+ bh->b_rsector = bh->b_blocknr;
generic_make_request (r1_bh->cmd, bh);
}
break;
@@ -1313,6 +1313,7 @@
struct buffer_head *bh;
int bsize;
int disk;
+ int block_nr;
spin_lock_irq(&conf->segment_lock);
if (!sector_nr) {
@@ -1383,11 +1384,11 @@
r1_bh->cmd = SPECIAL;
bh = &r1_bh->bh_req;
- bh->b_blocknr = sector_nr;
+ block_nr = sector_nr;
bsize = 512;
- while (!(bh->b_blocknr & 1) && bsize < PAGE_SIZE
- && (bh->b_blocknr+2)*(bsize>>9) < (mddev->sb->size *2)) {
- bh->b_blocknr >>= 1;
+ while (!(block_nr & 1) && bsize < PAGE_SIZE
+ && (block_nr+2)*(bsize>>9) < (mddev->sb->size *2)) {
+ block_nr >>= 1;
bsize <<= 1;
}
bh->b_size = bsize;
@@ -1403,6 +1404,7 @@
BUG();
bh->b_end_io = end_sync_read;
bh->b_private = r1_bh;
+ bh->b_blocknr = sector_nr;
bh->b_rsector = sector_nr;
init_waitqueue_head(&bh->b_wait);
@@ -1440,7 +1442,7 @@
md_error (r1_bh->mddev, bh->b_dev);
if (atomic_dec_and_test(&r1_bh->remaining)) {
mddev_t *mddev = r1_bh->mddev;
- unsigned long sect = bh->b_blocknr * (bh->b_size>>9);
+ unsigned long sect = bh->b_blocknr;
int size = bh->b_size;
raid1_free_buf(r1_bh);
sync_request_done(sect, mddev_to_conf(mddev));
-
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic