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, ¤t_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, ¤t_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, ¤t_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, ¤t_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.