All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <200701051506.52840.philipp.reisner@linbit.com>

diff --git a/a/1.txt b/N1/1.txt
index 67dd01f..822d744 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -29,17 +29,3 @@ PS2: I created the ocfs2-fix-bio_add_page.diff on 2.6.17 .
 : Dipl-Ing Philipp Reisner                      Tel +43-1-8178292-50 :
 : LINBIT Information Technologies GmbH          Fax +43-1-8178292-82 :
 : Vivenotgasse 48, 1120 Vienna, Austria        http://www.linbit.com :
--------------- next part --------------
-A non-text attachment was scrubbed...
-Name: ocfs2-fix-bio_add_page.diff
-Type: text/x-diff
-Size: 9363 bytes
-Desc: not available
-Url : http://oss.oracle.com/pipermail/ocfs2-devel/attachments/20070105/3ebcad56/ocfs2-fix-bio_add_page.bin
--------------- next part --------------
-A non-text attachment was scrubbed...
-Name: ocfs2-fix-bio_add_page-for-2.6.20-rc2.diff
-Type: text/x-diff
-Size: 8766 bytes
-Desc: not available
-Url : http://oss.oracle.com/pipermail/ocfs2-devel/attachments/20070105/3ebcad56/ocfs2-fix-bio_add_page-for-2.6.20-rc2.bin
diff --git a/N1/2.hdr b/N1/2.hdr
new file mode 100644
index 0000000..9fca61f
--- /dev/null
+++ b/N1/2.hdr
@@ -0,0 +1,5 @@
+Content-Type: text/x-diff; charset="us-ascii";
+	name="ocfs2-fix-bio_add_page.diff"
+Content-Transfer-Encoding: 7bit
+Content-Disposition: attachment;
+	filename="ocfs2-fix-bio_add_page.diff"
diff --git a/N1/2.txt b/N1/2.txt
new file mode 100644
index 0000000..7545506
--- /dev/null
+++ b/N1/2.txt
@@ -0,0 +1,305 @@
+diff -rup linux-2.6.17-kdb_orig/fs/ocfs2/cluster/heartbeat.c linux-2.6.17-kdb/fs/ocfs2/cluster/heartbeat.c
+--- linux-2.6.17-kdb_orig/fs/ocfs2/cluster/heartbeat.c	2007-01-05 11:29:06.696018258 +0100
++++ linux-2.6.17-kdb/fs/ocfs2/cluster/heartbeat.c	2007-01-05 14:08:00.133625148 +0100
+@@ -3,6 +3,8 @@
+  *
+  * Copyright (C) 2004, 2005 Oracle.  All rights reserved.
+  *
++ * 5. Jan 2007 Philipp Reisner, fixed the use of bio_add_page().
++ *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public
+  * License as published by the Free Software Foundation; either
+@@ -182,10 +184,9 @@ static void o2hb_disarm_write_timeout(st
+ 	flush_scheduled_work();
+ }
+ 
+-static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc,
+-				      unsigned int num_ios)
++static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc)
+ {
+-	atomic_set(&wc->wc_num_reqs, num_ios);
++	atomic_set(&wc->wc_num_reqs, 0);
+ 	init_completion(&wc->wc_io_complete);
+ 	wc->wc_error = 0;
+ }
+@@ -229,6 +230,7 @@ static int o2hb_bio_end_io(struct bio *b
+ 		return 1;
+ 
+ 	o2hb_bio_wait_dec(wc, 1);
++	bio_put(bio);
+ 	return 0;
+ }
+ 
+@@ -236,23 +238,22 @@ static int o2hb_bio_end_io(struct bio *b
+  * start_slot. */
+ static struct bio *o2hb_setup_one_bio(struct o2hb_region *reg,
+ 				      struct o2hb_bio_wait_ctxt *wc,
+-				      unsigned int start_slot,
+-				      unsigned int num_slots)
++				      unsigned int *current_slot,
++				      unsigned int max_slots)
+ {
+-	int i, nr_vecs, len, first_page, last_page;
++	int len, current_page;
+ 	unsigned int vec_len, vec_start;
+ 	unsigned int bits = reg->hr_block_bits;
+ 	unsigned int spp = reg->hr_slots_per_page;
++	unsigned int cs = *current_slot;
+ 	struct bio *bio;
+ 	struct page *page;
+ 
+-	nr_vecs = (num_slots + spp - 1) / spp;
+-
+ 	/* Testing has shown this allocation to take long enough under
+ 	 * GFP_KERNEL that the local node can get fenced. It would be
+ 	 * nicest if we could pre-allocate these bios and avoid this
+ 	 * all together. */
+-	bio = bio_alloc(GFP_ATOMIC, nr_vecs);
++	bio = bio_alloc(GFP_ATOMIC, 16);
+ 	if (!bio) {
+ 		mlog(ML_ERROR, "Could not alloc slots BIO!\n");
+ 		bio = ERR_PTR(-ENOMEM);
+@@ -260,133 +261,53 @@ static struct bio *o2hb_setup_one_bio(st
+ 	}
+ 
+ 	/* Must put everything in 512 byte sectors for the bio... */
+-	bio->bi_sector = (reg->hr_start_block + start_slot) << (bits - 9);
++	bio->bi_sector = (reg->hr_start_block + cs) << (bits - 9);
+ 	bio->bi_bdev = reg->hr_bdev;
+ 	bio->bi_private = wc;
+ 	bio->bi_end_io = o2hb_bio_end_io;
+ 
+-	first_page = start_slot / spp;
+-	last_page = first_page + nr_vecs;
+-	vec_start = (start_slot << bits) % PAGE_CACHE_SIZE;
+-	for(i = first_page; i < last_page; i++) {
+-		page = reg->hr_slot_data[i];
+-
+-		vec_len = PAGE_CACHE_SIZE;
+-		/* last page might be short */
+-		if (((i + 1) * spp) > (start_slot + num_slots))
+-			vec_len = ((num_slots + start_slot) % spp) << bits;
+-		vec_len -=  vec_start;
++	vec_start = (cs << bits) % PAGE_CACHE_SIZE;
++	while(cs < max_slots) {
++		current_page = cs / spp;
++		page = reg->hr_slot_data[current_page];
++
++		vec_len = min( PAGE_CACHE_SIZE, 
++			       (max_slots-cs) * (PAGE_CACHE_SIZE/spp) ); 
+ 
+ 		mlog(ML_HB_BIO, "page %d, vec_len = %u, vec_start = %u\n",
+-		     i, vec_len, vec_start);
++		     current_page, vec_len, vec_start);
+ 
+ 		len = bio_add_page(bio, page, vec_len, vec_start);
+-		if (len != vec_len) {
+-			bio_put(bio);
+-			bio = ERR_PTR(-EIO);
+-
+-			mlog(ML_ERROR, "Error adding page to bio i = %d, "
+-			     "vec_len = %u, len = %d\n, start = %u\n",
+-			     i, vec_len, len, vec_start);
+-			goto bail;
+-		}
++		if (len != vec_len) break;
+ 
++		cs += vec_len / (PAGE_CACHE_SIZE/spp);
+ 		vec_start = 0;
+ 	}
+ 
+ bail:
++	*current_slot = cs;
+ 	return bio;
+ }
+ 
+-/*
+- * Compute the maximum number of sectors the bdev can handle in one bio,
+- * as a power of two.
+- *
+- * Stolen from oracleasm, thanks Joel!
+- */
+-static int compute_max_sectors(struct block_device *bdev)
+-{
+-	int max_pages, max_sectors, pow_two_sectors;
+-
+-	struct request_queue *q;
+-
+-	q = bdev_get_queue(bdev);
+-	max_pages = q->max_sectors >> (PAGE_SHIFT - 9);
+-	if (max_pages > BIO_MAX_PAGES)
+-		max_pages = BIO_MAX_PAGES;
+-	if (max_pages > q->max_phys_segments)
+-		max_pages = q->max_phys_segments;
+-	if (max_pages > q->max_hw_segments)
+-		max_pages = q->max_hw_segments;
+-	max_pages--; /* Handle I/Os that straddle a page */
+-
+-	max_sectors = max_pages << (PAGE_SHIFT - 9);
+-
+-	/* Why is fls() 1-based???? */
+-	pow_two_sectors = 1 << (fls(max_sectors) - 1);
+-
+-	return pow_two_sectors;
+-}
+-
+-static inline void o2hb_compute_request_limits(struct o2hb_region *reg,
+-					       unsigned int num_slots,
+-					       unsigned int *num_bios,
+-					       unsigned int *slots_per_bio)
+-{
+-	unsigned int max_sectors, io_sectors;
+-
+-	max_sectors = compute_max_sectors(reg->hr_bdev);
+-
+-	io_sectors = num_slots << (reg->hr_block_bits - 9);
+-
+-	*num_bios = (io_sectors + max_sectors - 1) / max_sectors;
+-	*slots_per_bio = max_sectors >> (reg->hr_block_bits - 9);
+-
+-	mlog(ML_HB_BIO, "My io size is %u sectors for %u slots. This "
+-	     "device can handle %u sectors of I/O\n", io_sectors, num_slots,
+-	     max_sectors);
+-	mlog(ML_HB_BIO, "Will need %u bios holding %u slots each\n",
+-	     *num_bios, *slots_per_bio);
+-}
+-
+ static int o2hb_read_slots(struct o2hb_region *reg,
+ 			   unsigned int max_slots)
+ {
+-	unsigned int num_bios, slots_per_bio, start_slot, num_slots;
+-	int i, status;
++	unsigned int current_slot=0;
++	int status;
+ 	struct o2hb_bio_wait_ctxt wc;
+-	struct bio **bios;
+ 	struct bio *bio;
+ 
+-	o2hb_compute_request_limits(reg, max_slots, &num_bios, &slots_per_bio);
+-
+-	bios = kcalloc(num_bios, sizeof(struct bio *), GFP_KERNEL);
+-	if (!bios) {
+-		status = -ENOMEM;
+-		mlog_errno(status);
+-		return status;
+-	}
+-
+-	o2hb_bio_wait_init(&wc, num_bios);
+-
+-	num_slots = slots_per_bio;
+-	for(i = 0; i < num_bios; i++) {
+-		start_slot = i * slots_per_bio;
++	o2hb_bio_wait_init(&wc);
+ 
+-		/* adjust num_slots at last bio */
+-		if (max_slots < (start_slot + num_slots))
+-			num_slots = max_slots - start_slot;
+-
+-		bio = o2hb_setup_one_bio(reg, &wc, start_slot, num_slots);
++	while(current_slot < max_slots) {
++		bio = o2hb_setup_one_bio(reg, &wc, &current_slot, max_slots);
+ 		if (IS_ERR(bio)) {
+-			o2hb_bio_wait_dec(&wc, num_bios - i);
+-
+ 			status = PTR_ERR(bio);
+ 			mlog_errno(status);
+ 			goto bail_and_wait;
+ 		}
+-		bios[i] = bio;
+ 
++		atomic_inc(&wc.wc_num_reqs);
+ 		submit_bio(READ, bio);
+ 	}
+ 
+@@ -397,38 +318,30 @@ bail_and_wait:
+ 	if (wc.wc_error && !status)
+ 		status = wc.wc_error;
+ 
+-	if (bios) {
+-		for(i = 0; i < num_bios; i++)
+-			if (bios[i])
+-				bio_put(bios[i]);
+-		kfree(bios);
+-	}
+-
+ 	return status;
+ }
+ 
+ static int o2hb_issue_node_write(struct o2hb_region *reg,
+-				 struct bio **write_bio,
+ 				 struct o2hb_bio_wait_ctxt *write_wc)
+ {
+ 	int status;
+ 	unsigned int slot;
+ 	struct bio *bio;
+ 
+-	o2hb_bio_wait_init(write_wc, 1);
++	o2hb_bio_wait_init(write_wc);
+ 
+ 	slot = o2nm_this_node();
+ 
+-	bio = o2hb_setup_one_bio(reg, write_wc, slot, 1);
++	bio = o2hb_setup_one_bio(reg, write_wc, &slot, slot+1);
+ 	if (IS_ERR(bio)) {
+ 		status = PTR_ERR(bio);
+ 		mlog_errno(status);
+ 		goto bail;
+ 	}
+ 
++	atomic_inc(&write_wc->wc_num_reqs);
+ 	submit_bio(WRITE, bio);
+ 
+-	*write_bio = bio;
+ 	status = 0;
+ bail:
+ 	return status;
+@@ -800,7 +713,6 @@ static int o2hb_do_disk_heartbeat(struct
+ {
+ 	int i, ret, highest_node, change = 0;
+ 	unsigned long configured_nodes[BITS_TO_LONGS(O2NM_MAX_NODES)];
+-	struct bio *write_bio;
+ 	struct o2hb_bio_wait_ctxt write_wc;
+ 
+ 	ret = o2nm_configured_node_map(configured_nodes,
+@@ -838,7 +750,7 @@ static int o2hb_do_disk_heartbeat(struct
+ 
+ 	/* And fire off the write. Note that we don't wait on this I/O
+ 	 * until later. */
+-	ret = o2hb_issue_node_write(reg, &write_bio, &write_wc);
++	ret = o2hb_issue_node_write(reg, &write_wc);
+ 	if (ret < 0) {
+ 		mlog_errno(ret);
+ 		return ret;
+@@ -856,7 +768,6 @@ static int o2hb_do_disk_heartbeat(struct
+ 	 * people we find in our steady state have seen us.
+ 	 */
+ 	o2hb_wait_on_io(reg, &write_wc);
+-	bio_put(write_bio);
+ 	if (write_wc.wc_error) {
+ 		/* Do not re-arm the write timeout on I/O error - we
+ 		 * can't be sure that the new block ever made it to
+@@ -917,7 +828,6 @@ static int o2hb_thread(void *data)
+ {
+ 	int i, ret;
+ 	struct o2hb_region *reg = data;
+-	struct bio *write_bio;
+ 	struct o2hb_bio_wait_ctxt write_wc;
+ 	struct timeval before_hb, after_hb;
+ 	unsigned int elapsed_msec;
+@@ -967,10 +877,9 @@ static int o2hb_thread(void *data)
+ 	 *
+ 	 * XXX: Should we skip this on unclean_stop? */
+ 	o2hb_prepare_block(reg, 0);
+-	ret = o2hb_issue_node_write(reg, &write_bio, &write_wc);
++	ret = o2hb_issue_node_write(reg, &write_wc);
+ 	if (ret == 0) {
+ 		o2hb_wait_on_io(reg, &write_wc);
+-		bio_put(write_bio);
+ 	} else {
+ 		mlog_errno(ret);
+ 	}
+Binary files linux-2.6.17-kdb_orig/fs/ocfs2/cluster/heartbeat.o and linux-2.6.17-kdb/fs/ocfs2/cluster/heartbeat.o differ
+Binary files linux-2.6.17-kdb_orig/fs/ocfs2/cluster/ocfs2_nodemanager.ko and linux-2.6.17-kdb/fs/ocfs2/cluster/ocfs2_nodemanager.ko differ
+Binary files linux-2.6.17-kdb_orig/fs/ocfs2/cluster/ocfs2_nodemanager.mod.o and linux-2.6.17-kdb/fs/ocfs2/cluster/ocfs2_nodemanager.mod.o differ
+Binary files linux-2.6.17-kdb_orig/fs/ocfs2/cluster/ocfs2_nodemanager.o and linux-2.6.17-kdb/fs/ocfs2/cluster/ocfs2_nodemanager.o differ
diff --git a/N1/3.hdr b/N1/3.hdr
new file mode 100644
index 0000000..0429683
--- /dev/null
+++ b/N1/3.hdr
@@ -0,0 +1,5 @@
+Content-Type: text/x-diff; charset="us-ascii";
+	name="ocfs2-fix-bio_add_page-for-2.6.20-rc2.diff"
+Content-Transfer-Encoding: 7bit
+Content-Disposition: attachment;
+	filename="ocfs2-fix-bio_add_page-for-2.6.20-rc2.diff"
diff --git a/N1/3.txt b/N1/3.txt
new file mode 100644
index 0000000..caaef29
--- /dev/null
+++ b/N1/3.txt
@@ -0,0 +1,304 @@
+--- heartbeat-2.6.20-rc2.c	2007-01-05 14:56:13.000000000 +0100
++++ heartbeat.c	2007-01-05 15:02:08.000000000 +0100
+@@ -3,6 +3,8 @@
+  *
+  * Copyright (C) 2004, 2005 Oracle.  All rights reserved.
+  *
++ * 5. Jan 2007 Philipp Reisner, fixed the use of bio_add_page().
++ *
+  * This program is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public
+  * License as published by the Free Software Foundation; either
+@@ -184,10 +186,9 @@ static void o2hb_disarm_write_timeout(st
+ 	flush_scheduled_work();
+ }
+ 
+-static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc,
+-				      unsigned int num_ios)
++static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc)
+ {
+-	atomic_set(&wc->wc_num_reqs, num_ios);
++	atomic_set(&wc->wc_num_reqs, 0);
+ 	init_completion(&wc->wc_io_complete);
+ 	wc->wc_error = 0;
+ }
+@@ -231,6 +232,7 @@ static int o2hb_bio_end_io(struct bio *b
+ 		return 1;
+ 
+ 	o2hb_bio_wait_dec(wc, 1);
++	bio_put(bio);
+ 	return 0;
+ }
+ 
+@@ -238,23 +240,22 @@ static int o2hb_bio_end_io(struct bio *b
+  * start_slot. */
+ static struct bio *o2hb_setup_one_bio(struct o2hb_region *reg,
+ 				      struct o2hb_bio_wait_ctxt *wc,
+-				      unsigned int start_slot,
+-				      unsigned int num_slots)
++				      unsigned int *current_slot,
++				      unsigned int max_slots)
+ {
+-	int i, nr_vecs, len, first_page, last_page;
++	int len, current_page;
+ 	unsigned int vec_len, vec_start;
+ 	unsigned int bits = reg->hr_block_bits;
+ 	unsigned int spp = reg->hr_slots_per_page;
++	unsigned int cs = *current_slot;
+ 	struct bio *bio;
+ 	struct page *page;
+ 
+-	nr_vecs = (num_slots + spp - 1) / spp;
+-
+ 	/* Testing has shown this allocation to take long enough under
+ 	 * GFP_KERNEL that the local node can get fenced. It would be
+ 	 * nicest if we could pre-allocate these bios and avoid this
+ 	 * all together. */
+-	bio = bio_alloc(GFP_ATOMIC, nr_vecs);
++	bio = bio_alloc(GFP_ATOMIC, 16);
+ 	if (!bio) {
+ 		mlog(ML_ERROR, "Could not alloc slots BIO!\n");
+ 		bio = ERR_PTR(-ENOMEM);
+@@ -262,137 +263,53 @@ static struct bio *o2hb_setup_one_bio(st
+ 	}
+ 
+ 	/* Must put everything in 512 byte sectors for the bio... */
+-	bio->bi_sector = (reg->hr_start_block + start_slot) << (bits - 9);
++	bio->bi_sector = (reg->hr_start_block + cs) << (bits - 9);
+ 	bio->bi_bdev = reg->hr_bdev;
+ 	bio->bi_private = wc;
+ 	bio->bi_end_io = o2hb_bio_end_io;
+ 
+-	first_page = start_slot / spp;
+-	last_page = first_page + nr_vecs;
+-	vec_start = (start_slot << bits) % PAGE_CACHE_SIZE;
+-	for(i = first_page; i < last_page; i++) {
+-		page = reg->hr_slot_data[i];
+-
+-		vec_len = PAGE_CACHE_SIZE;
+-		/* last page might be short */
+-		if (((i + 1) * spp) > (start_slot + num_slots))
+-			vec_len = ((num_slots + start_slot) % spp) << bits;
+-		vec_len -=  vec_start;
++	vec_start = (cs << bits) % PAGE_CACHE_SIZE;
++	while(cs < max_slots) {
++		current_page = cs / spp;
++		page = reg->hr_slot_data[current_page];
++
++		vec_len = min( PAGE_CACHE_SIZE, 
++			       (max_slots-cs) * (PAGE_CACHE_SIZE/spp) ); 
+ 
+ 		mlog(ML_HB_BIO, "page %d, vec_len = %u, vec_start = %u\n",
+-		     i, vec_len, vec_start);
++		     current_page, vec_len, vec_start);
+ 
+ 		len = bio_add_page(bio, page, vec_len, vec_start);
+-		if (len != vec_len) {
+-			bio_put(bio);
+-			bio = ERR_PTR(-EIO);
+-
+-			mlog(ML_ERROR, "Error adding page to bio i = %d, "
+-			     "vec_len = %u, len = %d\n, start = %u\n",
+-			     i, vec_len, len, vec_start);
+-			goto bail;
+-		}
++		if (len != vec_len) break;
+ 
++		cs += vec_len / (PAGE_CACHE_SIZE/spp);
+ 		vec_start = 0;
+ 	}
+ 
+ bail:
++	*current_slot = cs;
+ 	return bio;
+ }
+ 
+-/*
+- * Compute the maximum number of sectors the bdev can handle in one bio,
+- * as a power of two.
+- *
+- * Stolen from oracleasm, thanks Joel!
+- */
+-static int compute_max_sectors(struct block_device *bdev)
+-{
+-	int max_pages, max_sectors, pow_two_sectors;
+-
+-	struct request_queue *q;
+-
+-	q = bdev_get_queue(bdev);
+-	max_pages = q->max_sectors >> (PAGE_SHIFT - 9);
+-	if (max_pages > BIO_MAX_PAGES)
+-		max_pages = BIO_MAX_PAGES;
+-	if (max_pages > q->max_phys_segments)
+-		max_pages = q->max_phys_segments;
+-	if (max_pages > q->max_hw_segments)
+-		max_pages = q->max_hw_segments;
+-	max_pages--; /* Handle I/Os that straddle a page */
+-
+-	if (max_pages) {
+-		max_sectors = max_pages << (PAGE_SHIFT - 9);
+-	} else {
+-		/* If BIO contains 1 or less than 1 page. */
+-		max_sectors = q->max_sectors;
+-	}
+-	/* Why is fls() 1-based???? */
+-	pow_two_sectors = 1 << (fls(max_sectors) - 1);
+-
+-	return pow_two_sectors;
+-}
+-
+-static inline void o2hb_compute_request_limits(struct o2hb_region *reg,
+-					       unsigned int num_slots,
+-					       unsigned int *num_bios,
+-					       unsigned int *slots_per_bio)
+-{
+-	unsigned int max_sectors, io_sectors;
+-
+-	max_sectors = compute_max_sectors(reg->hr_bdev);
+-
+-	io_sectors = num_slots << (reg->hr_block_bits - 9);
+-
+-	*num_bios = (io_sectors + max_sectors - 1) / max_sectors;
+-	*slots_per_bio = max_sectors >> (reg->hr_block_bits - 9);
+-
+-	mlog(ML_HB_BIO, "My io size is %u sectors for %u slots. This "
+-	     "device can handle %u sectors of I/O\n", io_sectors, num_slots,
+-	     max_sectors);
+-	mlog(ML_HB_BIO, "Will need %u bios holding %u slots each\n",
+-	     *num_bios, *slots_per_bio);
+-}
+-
+ static int o2hb_read_slots(struct o2hb_region *reg,
+ 			   unsigned int max_slots)
+ {
+-	unsigned int num_bios, slots_per_bio, start_slot, num_slots;
+-	int i, status;
++	unsigned int current_slot=0;
++	int status;
+ 	struct o2hb_bio_wait_ctxt wc;
+-	struct bio **bios;
+ 	struct bio *bio;
+ 
+-	o2hb_compute_request_limits(reg, max_slots, &num_bios, &slots_per_bio);
++	o2hb_bio_wait_init(&wc);
+ 
+-	bios = kcalloc(num_bios, sizeof(struct bio *), GFP_KERNEL);
+-	if (!bios) {
+-		status = -ENOMEM;
+-		mlog_errno(status);
+-		return status;
+-	}
+-
+-	o2hb_bio_wait_init(&wc, num_bios);
+-
+-	num_slots = slots_per_bio;
+-	for(i = 0; i < num_bios; i++) {
+-		start_slot = i * slots_per_bio;
+-
+-		/* adjust num_slots at last bio */
+-		if (max_slots < (start_slot + num_slots))
+-			num_slots = max_slots - start_slot;
+-
+-		bio = o2hb_setup_one_bio(reg, &wc, start_slot, num_slots);
++	while(current_slot < max_slots) {
++		bio = o2hb_setup_one_bio(reg, &wc, &current_slot, max_slots);
+ 		if (IS_ERR(bio)) {
+-			o2hb_bio_wait_dec(&wc, num_bios - i);
+-
+ 			status = PTR_ERR(bio);
+ 			mlog_errno(status);
+ 			goto bail_and_wait;
+ 		}
+-		bios[i] = bio;
+ 
++		atomic_inc(&wc.wc_num_reqs);
+ 		submit_bio(READ, bio);
+ 	}
+ 
+@@ -403,38 +320,30 @@ bail_and_wait:
+ 	if (wc.wc_error && !status)
+ 		status = wc.wc_error;
+ 
+-	if (bios) {
+-		for(i = 0; i < num_bios; i++)
+-			if (bios[i])
+-				bio_put(bios[i]);
+-		kfree(bios);
+-	}
+-
+ 	return status;
+ }
+ 
+ static int o2hb_issue_node_write(struct o2hb_region *reg,
+-				 struct bio **write_bio,
+ 				 struct o2hb_bio_wait_ctxt *write_wc)
+ {
+ 	int status;
+ 	unsigned int slot;
+ 	struct bio *bio;
+ 
+-	o2hb_bio_wait_init(write_wc, 1);
++	o2hb_bio_wait_init(write_wc);
+ 
+ 	slot = o2nm_this_node();
+ 
+-	bio = o2hb_setup_one_bio(reg, write_wc, slot, 1);
++	bio = o2hb_setup_one_bio(reg, write_wc, &slot, slot+1);
+ 	if (IS_ERR(bio)) {
+ 		status = PTR_ERR(bio);
+ 		mlog_errno(status);
+ 		goto bail;
+ 	}
+ 
++	atomic_inc(&write_wc->wc_num_reqs);
+ 	submit_bio(WRITE, bio);
+ 
+-	*write_bio = bio;
+ 	status = 0;
+ bail:
+ 	return status;
+@@ -826,7 +735,6 @@ static int o2hb_do_disk_heartbeat(struct
+ {
+ 	int i, ret, highest_node, change = 0;
+ 	unsigned long configured_nodes[BITS_TO_LONGS(O2NM_MAX_NODES)];
+-	struct bio *write_bio;
+ 	struct o2hb_bio_wait_ctxt write_wc;
+ 
+ 	ret = o2nm_configured_node_map(configured_nodes,
+@@ -864,7 +772,7 @@ static int o2hb_do_disk_heartbeat(struct
+ 
+ 	/* And fire off the write. Note that we don't wait on this I/O
+ 	 * until later. */
+-	ret = o2hb_issue_node_write(reg, &write_bio, &write_wc);
++	ret = o2hb_issue_node_write(reg, &write_wc);
+ 	if (ret < 0) {
+ 		mlog_errno(ret);
+ 		return ret;
+@@ -882,7 +790,6 @@ static int o2hb_do_disk_heartbeat(struct
+ 	 * people we find in our steady state have seen us.
+ 	 */
+ 	o2hb_wait_on_io(reg, &write_wc);
+-	bio_put(write_bio);
+ 	if (write_wc.wc_error) {
+ 		/* Do not re-arm the write timeout on I/O error - we
+ 		 * can't be sure that the new block ever made it to
+@@ -943,7 +850,6 @@ static int o2hb_thread(void *data)
+ {
+ 	int i, ret;
+ 	struct o2hb_region *reg = data;
+-	struct bio *write_bio;
+ 	struct o2hb_bio_wait_ctxt write_wc;
+ 	struct timeval before_hb, after_hb;
+ 	unsigned int elapsed_msec;
+@@ -993,10 +899,9 @@ static int o2hb_thread(void *data)
+ 	 *
+ 	 * XXX: Should we skip this on unclean_stop? */
+ 	o2hb_prepare_block(reg, 0);
+-	ret = o2hb_issue_node_write(reg, &write_bio, &write_wc);
++	ret = o2hb_issue_node_write(reg, &write_wc);
+ 	if (ret == 0) {
+ 		o2hb_wait_on_io(reg, &write_wc);
+-		bio_put(write_bio);
+ 	} else {
+ 		mlog_errno(ret);
+ 	}
diff --git a/a/content_digest b/N1/content_digest
index 03ccfdf..3a68f4a 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -1,8 +1,9 @@
  "From\0Philipp Reisner <philipp.reisner@linbit.com>\0"
- "Subject\0[Ocfs2-devel] Fixing cluster/heartbeat.c's use of bio_add_page()\0"
- "Date\0Fri Jan  5 06:07:33 2007\0"
+ "Subject\0[Drbd-dev] Fixing cluster/heartbeat.c's use of bio_add_page()\0"
+ "Date\0Fri, 5 Jan 2007 15:06:52 +0100\0"
  "To\0ocfs2-devel@oss.oracle.com\0"
- "\00:1\0"
+ "Cc\0drbd-dev@lists.linbit.com\0"
+ "\01:1\0"
  "b\0"
  "Hi There,\n"
  "\n"
@@ -34,20 +35,621 @@
  "-- \n"
  ": Dipl-Ing Philipp Reisner                      Tel +43-1-8178292-50 :\n"
  ": LINBIT Information Technologies GmbH          Fax +43-1-8178292-82 :\n"
- ": Vivenotgasse 48, 1120 Vienna, Austria        http://www.linbit.com :\n"
- "-------------- next part --------------\n"
- "A non-text attachment was scrubbed...\n"
- "Name: ocfs2-fix-bio_add_page.diff\n"
- "Type: text/x-diff\n"
- "Size: 9363 bytes\n"
- "Desc: not available\n"
- "Url : http://oss.oracle.com/pipermail/ocfs2-devel/attachments/20070105/3ebcad56/ocfs2-fix-bio_add_page.bin\n"
- "-------------- next part --------------\n"
- "A non-text attachment was scrubbed...\n"
- "Name: ocfs2-fix-bio_add_page-for-2.6.20-rc2.diff\n"
- "Type: text/x-diff\n"
- "Size: 8766 bytes\n"
- "Desc: not available\n"
- Url : http://oss.oracle.com/pipermail/ocfs2-devel/attachments/20070105/3ebcad56/ocfs2-fix-bio_add_page-for-2.6.20-rc2.bin
+ : Vivenotgasse 48, 1120 Vienna, Austria        http://www.linbit.com :
+ "\01:2\0"
+ "fn\0ocfs2-fix-bio_add_page.diff\0"
+ "b\0"
+ "diff -rup linux-2.6.17-kdb_orig/fs/ocfs2/cluster/heartbeat.c linux-2.6.17-kdb/fs/ocfs2/cluster/heartbeat.c\n"
+ "--- linux-2.6.17-kdb_orig/fs/ocfs2/cluster/heartbeat.c\t2007-01-05 11:29:06.696018258 +0100\n"
+ "+++ linux-2.6.17-kdb/fs/ocfs2/cluster/heartbeat.c\t2007-01-05 14:08:00.133625148 +0100\n"
+ "@@ -3,6 +3,8 @@\n"
+ "  *\n"
+ "  * Copyright (C) 2004, 2005 Oracle.  All rights reserved.\n"
+ "  *\n"
+ "+ * 5. Jan 2007 Philipp Reisner, fixed the use of bio_add_page().\n"
+ "+ *\n"
+ "  * This program is free software; you can redistribute it and/or\n"
+ "  * modify it under the terms of the GNU General Public\n"
+ "  * License as published by the Free Software Foundation; either\n"
+ "@@ -182,10 +184,9 @@ static void o2hb_disarm_write_timeout(st\n"
+ " \tflush_scheduled_work();\n"
+ " }\n"
+ " \n"
+ "-static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc,\n"
+ "-\t\t\t\t      unsigned int num_ios)\n"
+ "+static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc)\n"
+ " {\n"
+ "-\tatomic_set(&wc->wc_num_reqs, num_ios);\n"
+ "+\tatomic_set(&wc->wc_num_reqs, 0);\n"
+ " \tinit_completion(&wc->wc_io_complete);\n"
+ " \twc->wc_error = 0;\n"
+ " }\n"
+ "@@ -229,6 +230,7 @@ static int o2hb_bio_end_io(struct bio *b\n"
+ " \t\treturn 1;\n"
+ " \n"
+ " \to2hb_bio_wait_dec(wc, 1);\n"
+ "+\tbio_put(bio);\n"
+ " \treturn 0;\n"
+ " }\n"
+ " \n"
+ "@@ -236,23 +238,22 @@ static int o2hb_bio_end_io(struct bio *b\n"
+ "  * start_slot. */\n"
+ " static struct bio *o2hb_setup_one_bio(struct o2hb_region *reg,\n"
+ " \t\t\t\t      struct o2hb_bio_wait_ctxt *wc,\n"
+ "-\t\t\t\t      unsigned int start_slot,\n"
+ "-\t\t\t\t      unsigned int num_slots)\n"
+ "+\t\t\t\t      unsigned int *current_slot,\n"
+ "+\t\t\t\t      unsigned int max_slots)\n"
+ " {\n"
+ "-\tint i, nr_vecs, len, first_page, last_page;\n"
+ "+\tint len, current_page;\n"
+ " \tunsigned int vec_len, vec_start;\n"
+ " \tunsigned int bits = reg->hr_block_bits;\n"
+ " \tunsigned int spp = reg->hr_slots_per_page;\n"
+ "+\tunsigned int cs = *current_slot;\n"
+ " \tstruct bio *bio;\n"
+ " \tstruct page *page;\n"
+ " \n"
+ "-\tnr_vecs = (num_slots + spp - 1) / spp;\n"
+ "-\n"
+ " \t/* Testing has shown this allocation to take long enough under\n"
+ " \t * GFP_KERNEL that the local node can get fenced. It would be\n"
+ " \t * nicest if we could pre-allocate these bios and avoid this\n"
+ " \t * all together. */\n"
+ "-\tbio = bio_alloc(GFP_ATOMIC, nr_vecs);\n"
+ "+\tbio = bio_alloc(GFP_ATOMIC, 16);\n"
+ " \tif (!bio) {\n"
+ " \t\tmlog(ML_ERROR, \"Could not alloc slots BIO!\\n\");\n"
+ " \t\tbio = ERR_PTR(-ENOMEM);\n"
+ "@@ -260,133 +261,53 @@ static struct bio *o2hb_setup_one_bio(st\n"
+ " \t}\n"
+ " \n"
+ " \t/* Must put everything in 512 byte sectors for the bio... */\n"
+ "-\tbio->bi_sector = (reg->hr_start_block + start_slot) << (bits - 9);\n"
+ "+\tbio->bi_sector = (reg->hr_start_block + cs) << (bits - 9);\n"
+ " \tbio->bi_bdev = reg->hr_bdev;\n"
+ " \tbio->bi_private = wc;\n"
+ " \tbio->bi_end_io = o2hb_bio_end_io;\n"
+ " \n"
+ "-\tfirst_page = start_slot / spp;\n"
+ "-\tlast_page = first_page + nr_vecs;\n"
+ "-\tvec_start = (start_slot << bits) % PAGE_CACHE_SIZE;\n"
+ "-\tfor(i = first_page; i < last_page; i++) {\n"
+ "-\t\tpage = reg->hr_slot_data[i];\n"
+ "-\n"
+ "-\t\tvec_len = PAGE_CACHE_SIZE;\n"
+ "-\t\t/* last page might be short */\n"
+ "-\t\tif (((i + 1) * spp) > (start_slot + num_slots))\n"
+ "-\t\t\tvec_len = ((num_slots + start_slot) % spp) << bits;\n"
+ "-\t\tvec_len -=  vec_start;\n"
+ "+\tvec_start = (cs << bits) % PAGE_CACHE_SIZE;\n"
+ "+\twhile(cs < max_slots) {\n"
+ "+\t\tcurrent_page = cs / spp;\n"
+ "+\t\tpage = reg->hr_slot_data[current_page];\n"
+ "+\n"
+ "+\t\tvec_len = min( PAGE_CACHE_SIZE, \n"
+ "+\t\t\t       (max_slots-cs) * (PAGE_CACHE_SIZE/spp) ); \n"
+ " \n"
+ " \t\tmlog(ML_HB_BIO, \"page %d, vec_len = %u, vec_start = %u\\n\",\n"
+ "-\t\t     i, vec_len, vec_start);\n"
+ "+\t\t     current_page, vec_len, vec_start);\n"
+ " \n"
+ " \t\tlen = bio_add_page(bio, page, vec_len, vec_start);\n"
+ "-\t\tif (len != vec_len) {\n"
+ "-\t\t\tbio_put(bio);\n"
+ "-\t\t\tbio = ERR_PTR(-EIO);\n"
+ "-\n"
+ "-\t\t\tmlog(ML_ERROR, \"Error adding page to bio i = %d, \"\n"
+ "-\t\t\t     \"vec_len = %u, len = %d\\n, start = %u\\n\",\n"
+ "-\t\t\t     i, vec_len, len, vec_start);\n"
+ "-\t\t\tgoto bail;\n"
+ "-\t\t}\n"
+ "+\t\tif (len != vec_len) break;\n"
+ " \n"
+ "+\t\tcs += vec_len / (PAGE_CACHE_SIZE/spp);\n"
+ " \t\tvec_start = 0;\n"
+ " \t}\n"
+ " \n"
+ " bail:\n"
+ "+\t*current_slot = cs;\n"
+ " \treturn bio;\n"
+ " }\n"
+ " \n"
+ "-/*\n"
+ "- * Compute the maximum number of sectors the bdev can handle in one bio,\n"
+ "- * as a power of two.\n"
+ "- *\n"
+ "- * Stolen from oracleasm, thanks Joel!\n"
+ "- */\n"
+ "-static int compute_max_sectors(struct block_device *bdev)\n"
+ "-{\n"
+ "-\tint max_pages, max_sectors, pow_two_sectors;\n"
+ "-\n"
+ "-\tstruct request_queue *q;\n"
+ "-\n"
+ "-\tq = bdev_get_queue(bdev);\n"
+ "-\tmax_pages = q->max_sectors >> (PAGE_SHIFT - 9);\n"
+ "-\tif (max_pages > BIO_MAX_PAGES)\n"
+ "-\t\tmax_pages = BIO_MAX_PAGES;\n"
+ "-\tif (max_pages > q->max_phys_segments)\n"
+ "-\t\tmax_pages = q->max_phys_segments;\n"
+ "-\tif (max_pages > q->max_hw_segments)\n"
+ "-\t\tmax_pages = q->max_hw_segments;\n"
+ "-\tmax_pages--; /* Handle I/Os that straddle a page */\n"
+ "-\n"
+ "-\tmax_sectors = max_pages << (PAGE_SHIFT - 9);\n"
+ "-\n"
+ "-\t/* Why is fls() 1-based???? */\n"
+ "-\tpow_two_sectors = 1 << (fls(max_sectors) - 1);\n"
+ "-\n"
+ "-\treturn pow_two_sectors;\n"
+ "-}\n"
+ "-\n"
+ "-static inline void o2hb_compute_request_limits(struct o2hb_region *reg,\n"
+ "-\t\t\t\t\t       unsigned int num_slots,\n"
+ "-\t\t\t\t\t       unsigned int *num_bios,\n"
+ "-\t\t\t\t\t       unsigned int *slots_per_bio)\n"
+ "-{\n"
+ "-\tunsigned int max_sectors, io_sectors;\n"
+ "-\n"
+ "-\tmax_sectors = compute_max_sectors(reg->hr_bdev);\n"
+ "-\n"
+ "-\tio_sectors = num_slots << (reg->hr_block_bits - 9);\n"
+ "-\n"
+ "-\t*num_bios = (io_sectors + max_sectors - 1) / max_sectors;\n"
+ "-\t*slots_per_bio = max_sectors >> (reg->hr_block_bits - 9);\n"
+ "-\n"
+ "-\tmlog(ML_HB_BIO, \"My io size is %u sectors for %u slots. This \"\n"
+ "-\t     \"device can handle %u sectors of I/O\\n\", io_sectors, num_slots,\n"
+ "-\t     max_sectors);\n"
+ "-\tmlog(ML_HB_BIO, \"Will need %u bios holding %u slots each\\n\",\n"
+ "-\t     *num_bios, *slots_per_bio);\n"
+ "-}\n"
+ "-\n"
+ " static int o2hb_read_slots(struct o2hb_region *reg,\n"
+ " \t\t\t   unsigned int max_slots)\n"
+ " {\n"
+ "-\tunsigned int num_bios, slots_per_bio, start_slot, num_slots;\n"
+ "-\tint i, status;\n"
+ "+\tunsigned int current_slot=0;\n"
+ "+\tint status;\n"
+ " \tstruct o2hb_bio_wait_ctxt wc;\n"
+ "-\tstruct bio **bios;\n"
+ " \tstruct bio *bio;\n"
+ " \n"
+ "-\to2hb_compute_request_limits(reg, max_slots, &num_bios, &slots_per_bio);\n"
+ "-\n"
+ "-\tbios = kcalloc(num_bios, sizeof(struct bio *), GFP_KERNEL);\n"
+ "-\tif (!bios) {\n"
+ "-\t\tstatus = -ENOMEM;\n"
+ "-\t\tmlog_errno(status);\n"
+ "-\t\treturn status;\n"
+ "-\t}\n"
+ "-\n"
+ "-\to2hb_bio_wait_init(&wc, num_bios);\n"
+ "-\n"
+ "-\tnum_slots = slots_per_bio;\n"
+ "-\tfor(i = 0; i < num_bios; i++) {\n"
+ "-\t\tstart_slot = i * slots_per_bio;\n"
+ "+\to2hb_bio_wait_init(&wc);\n"
+ " \n"
+ "-\t\t/* adjust num_slots at last bio */\n"
+ "-\t\tif (max_slots < (start_slot + num_slots))\n"
+ "-\t\t\tnum_slots = max_slots - start_slot;\n"
+ "-\n"
+ "-\t\tbio = o2hb_setup_one_bio(reg, &wc, start_slot, num_slots);\n"
+ "+\twhile(current_slot < max_slots) {\n"
+ "+\t\tbio = o2hb_setup_one_bio(reg, &wc, &current_slot, max_slots);\n"
+ " \t\tif (IS_ERR(bio)) {\n"
+ "-\t\t\to2hb_bio_wait_dec(&wc, num_bios - i);\n"
+ "-\n"
+ " \t\t\tstatus = PTR_ERR(bio);\n"
+ " \t\t\tmlog_errno(status);\n"
+ " \t\t\tgoto bail_and_wait;\n"
+ " \t\t}\n"
+ "-\t\tbios[i] = bio;\n"
+ " \n"
+ "+\t\tatomic_inc(&wc.wc_num_reqs);\n"
+ " \t\tsubmit_bio(READ, bio);\n"
+ " \t}\n"
+ " \n"
+ "@@ -397,38 +318,30 @@ bail_and_wait:\n"
+ " \tif (wc.wc_error && !status)\n"
+ " \t\tstatus = wc.wc_error;\n"
+ " \n"
+ "-\tif (bios) {\n"
+ "-\t\tfor(i = 0; i < num_bios; i++)\n"
+ "-\t\t\tif (bios[i])\n"
+ "-\t\t\t\tbio_put(bios[i]);\n"
+ "-\t\tkfree(bios);\n"
+ "-\t}\n"
+ "-\n"
+ " \treturn status;\n"
+ " }\n"
+ " \n"
+ " static int o2hb_issue_node_write(struct o2hb_region *reg,\n"
+ "-\t\t\t\t struct bio **write_bio,\n"
+ " \t\t\t\t struct o2hb_bio_wait_ctxt *write_wc)\n"
+ " {\n"
+ " \tint status;\n"
+ " \tunsigned int slot;\n"
+ " \tstruct bio *bio;\n"
+ " \n"
+ "-\to2hb_bio_wait_init(write_wc, 1);\n"
+ "+\to2hb_bio_wait_init(write_wc);\n"
+ " \n"
+ " \tslot = o2nm_this_node();\n"
+ " \n"
+ "-\tbio = o2hb_setup_one_bio(reg, write_wc, slot, 1);\n"
+ "+\tbio = o2hb_setup_one_bio(reg, write_wc, &slot, slot+1);\n"
+ " \tif (IS_ERR(bio)) {\n"
+ " \t\tstatus = PTR_ERR(bio);\n"
+ " \t\tmlog_errno(status);\n"
+ " \t\tgoto bail;\n"
+ " \t}\n"
+ " \n"
+ "+\tatomic_inc(&write_wc->wc_num_reqs);\n"
+ " \tsubmit_bio(WRITE, bio);\n"
+ " \n"
+ "-\t*write_bio = bio;\n"
+ " \tstatus = 0;\n"
+ " bail:\n"
+ " \treturn status;\n"
+ "@@ -800,7 +713,6 @@ static int o2hb_do_disk_heartbeat(struct\n"
+ " {\n"
+ " \tint i, ret, highest_node, change = 0;\n"
+ " \tunsigned long configured_nodes[BITS_TO_LONGS(O2NM_MAX_NODES)];\n"
+ "-\tstruct bio *write_bio;\n"
+ " \tstruct o2hb_bio_wait_ctxt write_wc;\n"
+ " \n"
+ " \tret = o2nm_configured_node_map(configured_nodes,\n"
+ "@@ -838,7 +750,7 @@ static int o2hb_do_disk_heartbeat(struct\n"
+ " \n"
+ " \t/* And fire off the write. Note that we don't wait on this I/O\n"
+ " \t * until later. */\n"
+ "-\tret = o2hb_issue_node_write(reg, &write_bio, &write_wc);\n"
+ "+\tret = o2hb_issue_node_write(reg, &write_wc);\n"
+ " \tif (ret < 0) {\n"
+ " \t\tmlog_errno(ret);\n"
+ " \t\treturn ret;\n"
+ "@@ -856,7 +768,6 @@ static int o2hb_do_disk_heartbeat(struct\n"
+ " \t * people we find in our steady state have seen us.\n"
+ " \t */\n"
+ " \to2hb_wait_on_io(reg, &write_wc);\n"
+ "-\tbio_put(write_bio);\n"
+ " \tif (write_wc.wc_error) {\n"
+ " \t\t/* Do not re-arm the write timeout on I/O error - we\n"
+ " \t\t * can't be sure that the new block ever made it to\n"
+ "@@ -917,7 +828,6 @@ static int o2hb_thread(void *data)\n"
+ " {\n"
+ " \tint i, ret;\n"
+ " \tstruct o2hb_region *reg = data;\n"
+ "-\tstruct bio *write_bio;\n"
+ " \tstruct o2hb_bio_wait_ctxt write_wc;\n"
+ " \tstruct timeval before_hb, after_hb;\n"
+ " \tunsigned int elapsed_msec;\n"
+ "@@ -967,10 +877,9 @@ static int o2hb_thread(void *data)\n"
+ " \t *\n"
+ " \t * XXX: Should we skip this on unclean_stop? */\n"
+ " \to2hb_prepare_block(reg, 0);\n"
+ "-\tret = o2hb_issue_node_write(reg, &write_bio, &write_wc);\n"
+ "+\tret = o2hb_issue_node_write(reg, &write_wc);\n"
+ " \tif (ret == 0) {\n"
+ " \t\to2hb_wait_on_io(reg, &write_wc);\n"
+ "-\t\tbio_put(write_bio);\n"
+ " \t} else {\n"
+ " \t\tmlog_errno(ret);\n"
+ " \t}\n"
+ "Binary files linux-2.6.17-kdb_orig/fs/ocfs2/cluster/heartbeat.o and linux-2.6.17-kdb/fs/ocfs2/cluster/heartbeat.o differ\n"
+ "Binary files linux-2.6.17-kdb_orig/fs/ocfs2/cluster/ocfs2_nodemanager.ko and linux-2.6.17-kdb/fs/ocfs2/cluster/ocfs2_nodemanager.ko differ\n"
+ "Binary files linux-2.6.17-kdb_orig/fs/ocfs2/cluster/ocfs2_nodemanager.mod.o and linux-2.6.17-kdb/fs/ocfs2/cluster/ocfs2_nodemanager.mod.o differ\n"
+ Binary files linux-2.6.17-kdb_orig/fs/ocfs2/cluster/ocfs2_nodemanager.o and linux-2.6.17-kdb/fs/ocfs2/cluster/ocfs2_nodemanager.o differ
+ "\01:3\0"
+ "fn\0ocfs2-fix-bio_add_page-for-2.6.20-rc2.diff\0"
+ "b\0"
+ "--- heartbeat-2.6.20-rc2.c\t2007-01-05 14:56:13.000000000 +0100\n"
+ "+++ heartbeat.c\t2007-01-05 15:02:08.000000000 +0100\n"
+ "@@ -3,6 +3,8 @@\n"
+ "  *\n"
+ "  * Copyright (C) 2004, 2005 Oracle.  All rights reserved.\n"
+ "  *\n"
+ "+ * 5. Jan 2007 Philipp Reisner, fixed the use of bio_add_page().\n"
+ "+ *\n"
+ "  * This program is free software; you can redistribute it and/or\n"
+ "  * modify it under the terms of the GNU General Public\n"
+ "  * License as published by the Free Software Foundation; either\n"
+ "@@ -184,10 +186,9 @@ static void o2hb_disarm_write_timeout(st\n"
+ " \tflush_scheduled_work();\n"
+ " }\n"
+ " \n"
+ "-static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc,\n"
+ "-\t\t\t\t      unsigned int num_ios)\n"
+ "+static inline void o2hb_bio_wait_init(struct o2hb_bio_wait_ctxt *wc)\n"
+ " {\n"
+ "-\tatomic_set(&wc->wc_num_reqs, num_ios);\n"
+ "+\tatomic_set(&wc->wc_num_reqs, 0);\n"
+ " \tinit_completion(&wc->wc_io_complete);\n"
+ " \twc->wc_error = 0;\n"
+ " }\n"
+ "@@ -231,6 +232,7 @@ static int o2hb_bio_end_io(struct bio *b\n"
+ " \t\treturn 1;\n"
+ " \n"
+ " \to2hb_bio_wait_dec(wc, 1);\n"
+ "+\tbio_put(bio);\n"
+ " \treturn 0;\n"
+ " }\n"
+ " \n"
+ "@@ -238,23 +240,22 @@ static int o2hb_bio_end_io(struct bio *b\n"
+ "  * start_slot. */\n"
+ " static struct bio *o2hb_setup_one_bio(struct o2hb_region *reg,\n"
+ " \t\t\t\t      struct o2hb_bio_wait_ctxt *wc,\n"
+ "-\t\t\t\t      unsigned int start_slot,\n"
+ "-\t\t\t\t      unsigned int num_slots)\n"
+ "+\t\t\t\t      unsigned int *current_slot,\n"
+ "+\t\t\t\t      unsigned int max_slots)\n"
+ " {\n"
+ "-\tint i, nr_vecs, len, first_page, last_page;\n"
+ "+\tint len, current_page;\n"
+ " \tunsigned int vec_len, vec_start;\n"
+ " \tunsigned int bits = reg->hr_block_bits;\n"
+ " \tunsigned int spp = reg->hr_slots_per_page;\n"
+ "+\tunsigned int cs = *current_slot;\n"
+ " \tstruct bio *bio;\n"
+ " \tstruct page *page;\n"
+ " \n"
+ "-\tnr_vecs = (num_slots + spp - 1) / spp;\n"
+ "-\n"
+ " \t/* Testing has shown this allocation to take long enough under\n"
+ " \t * GFP_KERNEL that the local node can get fenced. It would be\n"
+ " \t * nicest if we could pre-allocate these bios and avoid this\n"
+ " \t * all together. */\n"
+ "-\tbio = bio_alloc(GFP_ATOMIC, nr_vecs);\n"
+ "+\tbio = bio_alloc(GFP_ATOMIC, 16);\n"
+ " \tif (!bio) {\n"
+ " \t\tmlog(ML_ERROR, \"Could not alloc slots BIO!\\n\");\n"
+ " \t\tbio = ERR_PTR(-ENOMEM);\n"
+ "@@ -262,137 +263,53 @@ static struct bio *o2hb_setup_one_bio(st\n"
+ " \t}\n"
+ " \n"
+ " \t/* Must put everything in 512 byte sectors for the bio... */\n"
+ "-\tbio->bi_sector = (reg->hr_start_block + start_slot) << (bits - 9);\n"
+ "+\tbio->bi_sector = (reg->hr_start_block + cs) << (bits - 9);\n"
+ " \tbio->bi_bdev = reg->hr_bdev;\n"
+ " \tbio->bi_private = wc;\n"
+ " \tbio->bi_end_io = o2hb_bio_end_io;\n"
+ " \n"
+ "-\tfirst_page = start_slot / spp;\n"
+ "-\tlast_page = first_page + nr_vecs;\n"
+ "-\tvec_start = (start_slot << bits) % PAGE_CACHE_SIZE;\n"
+ "-\tfor(i = first_page; i < last_page; i++) {\n"
+ "-\t\tpage = reg->hr_slot_data[i];\n"
+ "-\n"
+ "-\t\tvec_len = PAGE_CACHE_SIZE;\n"
+ "-\t\t/* last page might be short */\n"
+ "-\t\tif (((i + 1) * spp) > (start_slot + num_slots))\n"
+ "-\t\t\tvec_len = ((num_slots + start_slot) % spp) << bits;\n"
+ "-\t\tvec_len -=  vec_start;\n"
+ "+\tvec_start = (cs << bits) % PAGE_CACHE_SIZE;\n"
+ "+\twhile(cs < max_slots) {\n"
+ "+\t\tcurrent_page = cs / spp;\n"
+ "+\t\tpage = reg->hr_slot_data[current_page];\n"
+ "+\n"
+ "+\t\tvec_len = min( PAGE_CACHE_SIZE, \n"
+ "+\t\t\t       (max_slots-cs) * (PAGE_CACHE_SIZE/spp) ); \n"
+ " \n"
+ " \t\tmlog(ML_HB_BIO, \"page %d, vec_len = %u, vec_start = %u\\n\",\n"
+ "-\t\t     i, vec_len, vec_start);\n"
+ "+\t\t     current_page, vec_len, vec_start);\n"
+ " \n"
+ " \t\tlen = bio_add_page(bio, page, vec_len, vec_start);\n"
+ "-\t\tif (len != vec_len) {\n"
+ "-\t\t\tbio_put(bio);\n"
+ "-\t\t\tbio = ERR_PTR(-EIO);\n"
+ "-\n"
+ "-\t\t\tmlog(ML_ERROR, \"Error adding page to bio i = %d, \"\n"
+ "-\t\t\t     \"vec_len = %u, len = %d\\n, start = %u\\n\",\n"
+ "-\t\t\t     i, vec_len, len, vec_start);\n"
+ "-\t\t\tgoto bail;\n"
+ "-\t\t}\n"
+ "+\t\tif (len != vec_len) break;\n"
+ " \n"
+ "+\t\tcs += vec_len / (PAGE_CACHE_SIZE/spp);\n"
+ " \t\tvec_start = 0;\n"
+ " \t}\n"
+ " \n"
+ " bail:\n"
+ "+\t*current_slot = cs;\n"
+ " \treturn bio;\n"
+ " }\n"
+ " \n"
+ "-/*\n"
+ "- * Compute the maximum number of sectors the bdev can handle in one bio,\n"
+ "- * as a power of two.\n"
+ "- *\n"
+ "- * Stolen from oracleasm, thanks Joel!\n"
+ "- */\n"
+ "-static int compute_max_sectors(struct block_device *bdev)\n"
+ "-{\n"
+ "-\tint max_pages, max_sectors, pow_two_sectors;\n"
+ "-\n"
+ "-\tstruct request_queue *q;\n"
+ "-\n"
+ "-\tq = bdev_get_queue(bdev);\n"
+ "-\tmax_pages = q->max_sectors >> (PAGE_SHIFT - 9);\n"
+ "-\tif (max_pages > BIO_MAX_PAGES)\n"
+ "-\t\tmax_pages = BIO_MAX_PAGES;\n"
+ "-\tif (max_pages > q->max_phys_segments)\n"
+ "-\t\tmax_pages = q->max_phys_segments;\n"
+ "-\tif (max_pages > q->max_hw_segments)\n"
+ "-\t\tmax_pages = q->max_hw_segments;\n"
+ "-\tmax_pages--; /* Handle I/Os that straddle a page */\n"
+ "-\n"
+ "-\tif (max_pages) {\n"
+ "-\t\tmax_sectors = max_pages << (PAGE_SHIFT - 9);\n"
+ "-\t} else {\n"
+ "-\t\t/* If BIO contains 1 or less than 1 page. */\n"
+ "-\t\tmax_sectors = q->max_sectors;\n"
+ "-\t}\n"
+ "-\t/* Why is fls() 1-based???? */\n"
+ "-\tpow_two_sectors = 1 << (fls(max_sectors) - 1);\n"
+ "-\n"
+ "-\treturn pow_two_sectors;\n"
+ "-}\n"
+ "-\n"
+ "-static inline void o2hb_compute_request_limits(struct o2hb_region *reg,\n"
+ "-\t\t\t\t\t       unsigned int num_slots,\n"
+ "-\t\t\t\t\t       unsigned int *num_bios,\n"
+ "-\t\t\t\t\t       unsigned int *slots_per_bio)\n"
+ "-{\n"
+ "-\tunsigned int max_sectors, io_sectors;\n"
+ "-\n"
+ "-\tmax_sectors = compute_max_sectors(reg->hr_bdev);\n"
+ "-\n"
+ "-\tio_sectors = num_slots << (reg->hr_block_bits - 9);\n"
+ "-\n"
+ "-\t*num_bios = (io_sectors + max_sectors - 1) / max_sectors;\n"
+ "-\t*slots_per_bio = max_sectors >> (reg->hr_block_bits - 9);\n"
+ "-\n"
+ "-\tmlog(ML_HB_BIO, \"My io size is %u sectors for %u slots. This \"\n"
+ "-\t     \"device can handle %u sectors of I/O\\n\", io_sectors, num_slots,\n"
+ "-\t     max_sectors);\n"
+ "-\tmlog(ML_HB_BIO, \"Will need %u bios holding %u slots each\\n\",\n"
+ "-\t     *num_bios, *slots_per_bio);\n"
+ "-}\n"
+ "-\n"
+ " static int o2hb_read_slots(struct o2hb_region *reg,\n"
+ " \t\t\t   unsigned int max_slots)\n"
+ " {\n"
+ "-\tunsigned int num_bios, slots_per_bio, start_slot, num_slots;\n"
+ "-\tint i, status;\n"
+ "+\tunsigned int current_slot=0;\n"
+ "+\tint status;\n"
+ " \tstruct o2hb_bio_wait_ctxt wc;\n"
+ "-\tstruct bio **bios;\n"
+ " \tstruct bio *bio;\n"
+ " \n"
+ "-\to2hb_compute_request_limits(reg, max_slots, &num_bios, &slots_per_bio);\n"
+ "+\to2hb_bio_wait_init(&wc);\n"
+ " \n"
+ "-\tbios = kcalloc(num_bios, sizeof(struct bio *), GFP_KERNEL);\n"
+ "-\tif (!bios) {\n"
+ "-\t\tstatus = -ENOMEM;\n"
+ "-\t\tmlog_errno(status);\n"
+ "-\t\treturn status;\n"
+ "-\t}\n"
+ "-\n"
+ "-\to2hb_bio_wait_init(&wc, num_bios);\n"
+ "-\n"
+ "-\tnum_slots = slots_per_bio;\n"
+ "-\tfor(i = 0; i < num_bios; i++) {\n"
+ "-\t\tstart_slot = i * slots_per_bio;\n"
+ "-\n"
+ "-\t\t/* adjust num_slots at last bio */\n"
+ "-\t\tif (max_slots < (start_slot + num_slots))\n"
+ "-\t\t\tnum_slots = max_slots - start_slot;\n"
+ "-\n"
+ "-\t\tbio = o2hb_setup_one_bio(reg, &wc, start_slot, num_slots);\n"
+ "+\twhile(current_slot < max_slots) {\n"
+ "+\t\tbio = o2hb_setup_one_bio(reg, &wc, &current_slot, max_slots);\n"
+ " \t\tif (IS_ERR(bio)) {\n"
+ "-\t\t\to2hb_bio_wait_dec(&wc, num_bios - i);\n"
+ "-\n"
+ " \t\t\tstatus = PTR_ERR(bio);\n"
+ " \t\t\tmlog_errno(status);\n"
+ " \t\t\tgoto bail_and_wait;\n"
+ " \t\t}\n"
+ "-\t\tbios[i] = bio;\n"
+ " \n"
+ "+\t\tatomic_inc(&wc.wc_num_reqs);\n"
+ " \t\tsubmit_bio(READ, bio);\n"
+ " \t}\n"
+ " \n"
+ "@@ -403,38 +320,30 @@ bail_and_wait:\n"
+ " \tif (wc.wc_error && !status)\n"
+ " \t\tstatus = wc.wc_error;\n"
+ " \n"
+ "-\tif (bios) {\n"
+ "-\t\tfor(i = 0; i < num_bios; i++)\n"
+ "-\t\t\tif (bios[i])\n"
+ "-\t\t\t\tbio_put(bios[i]);\n"
+ "-\t\tkfree(bios);\n"
+ "-\t}\n"
+ "-\n"
+ " \treturn status;\n"
+ " }\n"
+ " \n"
+ " static int o2hb_issue_node_write(struct o2hb_region *reg,\n"
+ "-\t\t\t\t struct bio **write_bio,\n"
+ " \t\t\t\t struct o2hb_bio_wait_ctxt *write_wc)\n"
+ " {\n"
+ " \tint status;\n"
+ " \tunsigned int slot;\n"
+ " \tstruct bio *bio;\n"
+ " \n"
+ "-\to2hb_bio_wait_init(write_wc, 1);\n"
+ "+\to2hb_bio_wait_init(write_wc);\n"
+ " \n"
+ " \tslot = o2nm_this_node();\n"
+ " \n"
+ "-\tbio = o2hb_setup_one_bio(reg, write_wc, slot, 1);\n"
+ "+\tbio = o2hb_setup_one_bio(reg, write_wc, &slot, slot+1);\n"
+ " \tif (IS_ERR(bio)) {\n"
+ " \t\tstatus = PTR_ERR(bio);\n"
+ " \t\tmlog_errno(status);\n"
+ " \t\tgoto bail;\n"
+ " \t}\n"
+ " \n"
+ "+\tatomic_inc(&write_wc->wc_num_reqs);\n"
+ " \tsubmit_bio(WRITE, bio);\n"
+ " \n"
+ "-\t*write_bio = bio;\n"
+ " \tstatus = 0;\n"
+ " bail:\n"
+ " \treturn status;\n"
+ "@@ -826,7 +735,6 @@ static int o2hb_do_disk_heartbeat(struct\n"
+ " {\n"
+ " \tint i, ret, highest_node, change = 0;\n"
+ " \tunsigned long configured_nodes[BITS_TO_LONGS(O2NM_MAX_NODES)];\n"
+ "-\tstruct bio *write_bio;\n"
+ " \tstruct o2hb_bio_wait_ctxt write_wc;\n"
+ " \n"
+ " \tret = o2nm_configured_node_map(configured_nodes,\n"
+ "@@ -864,7 +772,7 @@ static int o2hb_do_disk_heartbeat(struct\n"
+ " \n"
+ " \t/* And fire off the write. Note that we don't wait on this I/O\n"
+ " \t * until later. */\n"
+ "-\tret = o2hb_issue_node_write(reg, &write_bio, &write_wc);\n"
+ "+\tret = o2hb_issue_node_write(reg, &write_wc);\n"
+ " \tif (ret < 0) {\n"
+ " \t\tmlog_errno(ret);\n"
+ " \t\treturn ret;\n"
+ "@@ -882,7 +790,6 @@ static int o2hb_do_disk_heartbeat(struct\n"
+ " \t * people we find in our steady state have seen us.\n"
+ " \t */\n"
+ " \to2hb_wait_on_io(reg, &write_wc);\n"
+ "-\tbio_put(write_bio);\n"
+ " \tif (write_wc.wc_error) {\n"
+ " \t\t/* Do not re-arm the write timeout on I/O error - we\n"
+ " \t\t * can't be sure that the new block ever made it to\n"
+ "@@ -943,7 +850,6 @@ static int o2hb_thread(void *data)\n"
+ " {\n"
+ " \tint i, ret;\n"
+ " \tstruct o2hb_region *reg = data;\n"
+ "-\tstruct bio *write_bio;\n"
+ " \tstruct o2hb_bio_wait_ctxt write_wc;\n"
+ " \tstruct timeval before_hb, after_hb;\n"
+ " \tunsigned int elapsed_msec;\n"
+ "@@ -993,10 +899,9 @@ static int o2hb_thread(void *data)\n"
+ " \t *\n"
+ " \t * XXX: Should we skip this on unclean_stop? */\n"
+ " \to2hb_prepare_block(reg, 0);\n"
+ "-\tret = o2hb_issue_node_write(reg, &write_bio, &write_wc);\n"
+ "+\tret = o2hb_issue_node_write(reg, &write_wc);\n"
+ " \tif (ret == 0) {\n"
+ " \t\to2hb_wait_on_io(reg, &write_wc);\n"
+ "-\t\tbio_put(write_bio);\n"
+ " \t} else {\n"
+ " \t\tmlog_errno(ret);\n"
+ " \t}"
 
-e328bb4cac9122dbfe8f4b78aeae47dbbf6d618f7f3a50a355f30ad7df2cf498
+a9cc8132e27a257c889afbd0f116da1e5d80aa57a26ff4fcf7aa72f18a61bf81

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.