aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'block/blk-core.c')
-rw-r--r--block/blk-core.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index 25f25271b42a..be43481bcb12 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -2023,7 +2023,14 @@ end_io:
2023 */ 2023 */
2024blk_qc_t generic_make_request(struct bio *bio) 2024blk_qc_t generic_make_request(struct bio *bio)
2025{ 2025{
2026 struct bio_list bio_list_on_stack; 2026 /*
2027 * bio_list_on_stack[0] contains bios submitted by the current
2028 * make_request_fn.
2029 * bio_list_on_stack[1] contains bios that were submitted before
2030 * the current make_request_fn, but that haven't been processed
2031 * yet.
2032 */
2033 struct bio_list bio_list_on_stack[2];
2027 blk_qc_t ret = BLK_QC_T_NONE; 2034 blk_qc_t ret = BLK_QC_T_NONE;
2028 2035
2029 if (!generic_make_request_checks(bio)) 2036 if (!generic_make_request_checks(bio))
@@ -2040,7 +2047,7 @@ blk_qc_t generic_make_request(struct bio *bio)
2040 * should be added at the tail 2047 * should be added at the tail
2041 */ 2048 */
2042 if (current->bio_list) { 2049 if (current->bio_list) {
2043 bio_list_add(current->bio_list, bio); 2050 bio_list_add(&current->bio_list[0], bio);
2044 goto out; 2051 goto out;
2045 } 2052 }
2046 2053
@@ -2059,24 +2066,39 @@ blk_qc_t generic_make_request(struct bio *bio)
2059 * bio_list, and call into ->make_request() again. 2066 * bio_list, and call into ->make_request() again.
2060 */ 2067 */
2061 BUG_ON(bio->bi_next); 2068 BUG_ON(bio->bi_next);
2062 bio_list_init(&bio_list_on_stack); 2069 bio_list_init(&bio_list_on_stack[0]);
2063 current->bio_list = &bio_list_on_stack; 2070 current->bio_list = bio_list_on_stack;
2064 do { 2071 do {
2065 struct request_queue *q = bdev_get_queue(bio->bi_bdev); 2072 struct request_queue *q = bdev_get_queue(bio->bi_bdev);
2066 2073
2067 if (likely(blk_queue_enter(q, __GFP_DIRECT_RECLAIM) == 0)) { 2074 if (likely(blk_queue_enter(q, __GFP_DIRECT_RECLAIM) == 0)) {
2075 struct bio_list lower, same;
2076
2077 /* Create a fresh bio_list for all subordinate requests */
2078 bio_list_on_stack[1] = bio_list_on_stack[0];
2079 bio_list_init(&bio_list_on_stack[0]);
2068 2080
2069 ret = q->make_request_fn(q, bio); 2081 ret = q->make_request_fn(q, bio);
2070 2082
2071 blk_queue_exit(q); 2083 blk_queue_exit(q);
2072 2084 /* sort new bios into those for a lower level
2073 bio = bio_list_pop(current->bio_list); 2085 * and those for the same level
2086 */
2087 bio_list_init(&lower);
2088 bio_list_init(&same);
2089 while ((bio = bio_list_pop(&bio_list_on_stack[0])) != NULL)
2090 if (q == bdev_get_queue(bio->bi_bdev))
2091 bio_list_add(&same, bio);
2092 else
2093 bio_list_add(&lower, bio);
2094 /* now assemble so we handle the lowest level first */
2095 bio_list_merge(&bio_list_on_stack[0], &lower);
2096 bio_list_merge(&bio_list_on_stack[0], &same);
2097 bio_list_merge(&bio_list_on_stack[0], &bio_list_on_stack[1]);
2074 } else { 2098 } else {
2075 struct bio *bio_next = bio_list_pop(current->bio_list);
2076
2077 bio_io_error(bio); 2099 bio_io_error(bio);
2078 bio = bio_next;
2079 } 2100 }
2101 bio = bio_list_pop(&bio_list_on_stack[0]);
2080 } while (bio); 2102 } while (bio);
2081 current->bio_list = NULL; /* deactivate */ 2103 current->bio_list = NULL; /* deactivate */
2082 2104