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 [EMAIL PROTECTED]

Reply via email to