<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
From: NeilBrown &lt;neilb@cse.unsw.edu.au&gt;

For each resync request, we allocate a "r1_bio" which has a bio "master_bio"
attached that goes largely unused.  We also allocate a read_bio which is
used.  This patch removes the read_bio and just uses the master_bio instead.

This fixes a bug wherein bi_bdev of the master_bio wasn't being set, but was
being used.

We also introduce a new "sectors" field into the r1_bio as we can no-longer
rely in master_bio-&gt;bi_sectors.



---

 drivers/md/raid1.c         |   37 ++++++++++++++++++-------------------
 include/linux/raid/raid1.h |    1 +
 2 files changed, 19 insertions(+), 19 deletions(-)

diff -puN drivers/md/raid1.c~md-05-avoid-bio-allocation drivers/md/raid1.c
--- 25/drivers/md/raid1.c~md-05-avoid-bio-allocation	2004-02-05 22:06:03.000000000 -0800
+++ 25-akpm/drivers/md/raid1.c	2004-02-05 22:06:03.000000000 -0800
@@ -77,6 +77,9 @@ static void * r1buf_pool_alloc(int gfp_f
 	if (!bio)
 		goto out_free_r1_bio;
 
+	/*
+	 * Allocate RESYNC_PAGES data pages for this iovec.
+	 */
 	for (i = 0; i &lt; RESYNC_PAGES; i++) {
 		page = alloc_page(gfp_flags);
 		if (unlikely(!page))
@@ -87,9 +90,6 @@ static void * r1buf_pool_alloc(int gfp_f
 		bio-&gt;bi_io_vec[i].bv_offset = 0;
 	}
 
-	/*
-	 * Allocate a single data page for this iovec.
-	 */
 	bio-&gt;bi_vcnt = RESYNC_PAGES;
 	bio-&gt;bi_idx = 0;
 	bio-&gt;bi_size = RESYNC_BLOCK_SIZE;
@@ -122,8 +122,6 @@ static void r1buf_pool_free(void *__r1_b
 		__free_page(bio-&gt;bi_io_vec[i].bv_page);
 		bio-&gt;bi_io_vec[i].bv_page = NULL;
 	}
-	if (atomic_read(&amp;bio-&gt;bi_cnt) != 1)
-		BUG();
 	bio_put(bio);
 	r1bio_pool_free(r1bio, conf-&gt;mddev);
 }
@@ -249,7 +247,7 @@ static inline void update_head_pos(int d
 	conf_t *conf = mddev_to_conf(r1_bio-&gt;mddev);
 
 	conf-&gt;mirrors[disk].head_position =
-		r1_bio-&gt;sector + (r1_bio-&gt;master_bio-&gt;bi_size &gt;&gt; 9);
+		r1_bio-&gt;sector + (r1_bio-&gt;sectors);
 }
 
 static int raid1_end_read_request(struct bio *bio, unsigned int bytes_done, int error)
@@ -507,6 +505,7 @@ static int make_request(request_queue_t 
 	r1_bio = mempool_alloc(conf-&gt;r1bio_pool, GFP_NOIO);
 
 	r1_bio-&gt;master_bio = bio;
+	r1_bio-&gt;sectors = bio-&gt;bi_size &gt;&gt; 9;
 
 	r1_bio-&gt;mddev = mddev;
 	r1_bio-&gt;sector = bio-&gt;bi_sector;
@@ -799,7 +798,7 @@ static int end_sync_write(struct bio *bi
 	update_head_pos(mirror, r1_bio);
 
 	if (atomic_dec_and_test(&amp;r1_bio-&gt;remaining)) {
-		md_done_sync(mddev, r1_bio-&gt;master_bio-&gt;bi_size &gt;&gt; 9, uptodate);
+		md_done_sync(mddev, r1_bio-&gt;sectors, uptodate);
 		put_buf(r1_bio);
 	}
 	atomic_dec(&amp;conf-&gt;mirrors[mirror].rdev-&gt;nr_pending);
@@ -829,7 +828,7 @@ static void sync_request_write(mddev_t *
 			" for block %llu\n",
 			bdevname(bio-&gt;bi_bdev,b), 
 			(unsigned long long)r1_bio-&gt;sector);
-		md_done_sync(mddev, r1_bio-&gt;master_bio-&gt;bi_size &gt;&gt; 9, 0);
+		md_done_sync(mddev, r1_bio-&gt;sectors, 0);
 		put_buf(r1_bio);
 		return;
 	}
@@ -874,7 +873,7 @@ static void sync_request_write(mddev_t *
 	}
 
 	if (atomic_dec_and_test(&amp;r1_bio-&gt;remaining)) {
-		md_done_sync(mddev, r1_bio-&gt;master_bio-&gt;bi_size &gt;&gt; 9, 1);
+		md_done_sync(mddev, r1_bio-&gt;sectors, 1);
 		put_buf(r1_bio);
 	}
 }
@@ -966,7 +965,7 @@ static int sync_request(mddev_t *mddev, 
 	conf_t *conf = mddev_to_conf(mddev);
 	mirror_info_t *mirror;
 	r1bio_t *r1_bio;
-	struct bio *read_bio, *bio;
+	struct bio *bio;
 	sector_t max_sector, nr_sectors;
 	int disk, partial;
 
@@ -1035,18 +1034,18 @@ static int sync_request(mddev_t *mddev, 
 		bio-&gt;bi_io_vec[bio-&gt;bi_vcnt-1].bv_len = partial;
 
 
-	read_bio = bio_clone(r1_bio-&gt;master_bio, GFP_NOIO);
-
-	read_bio-&gt;bi_sector = sector_nr + mirror-&gt;rdev-&gt;data_offset;
-	read_bio-&gt;bi_bdev = mirror-&gt;rdev-&gt;bdev;
-	read_bio-&gt;bi_end_io = end_sync_read;
-	read_bio-&gt;bi_rw = READ;
-	read_bio-&gt;bi_private = r1_bio;
-	r1_bio-&gt;bios[r1_bio-&gt;read_disk] = read_bio;
+	bio-&gt;bi_sector = sector_nr + mirror-&gt;rdev-&gt;data_offset;
+	bio-&gt;bi_bdev = mirror-&gt;rdev-&gt;bdev;
+	bio-&gt;bi_end_io = end_sync_read;
+	bio-&gt;bi_rw = READ;
+	bio-&gt;bi_private = r1_bio;
+	bio_get(bio);
+	r1_bio-&gt;bios[r1_bio-&gt;read_disk] = bio;
+	r1_bio-&gt;sectors = nr_sectors;
 
 	md_sync_acct(mirror-&gt;rdev, nr_sectors);
 
-	generic_make_request(read_bio);
+	generic_make_request(bio);
 
 	return nr_sectors;
 }
diff -puN include/linux/raid/raid1.h~md-05-avoid-bio-allocation include/linux/raid/raid1.h
--- 25/include/linux/raid/raid1.h~md-05-avoid-bio-allocation	2004-02-05 22:06:03.000000000 -0800
+++ 25-akpm/include/linux/raid/raid1.h	2004-02-05 22:06:03.000000000 -0800
@@ -55,6 +55,7 @@ struct r1bio_s {
 					    * used from IRQ handlers
 					    */
 	sector_t		sector;
+	int			sectors;
 	unsigned long		state;
 	mddev_t			*mddev;
 	/*

_
</pre></body></html>