[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