diff options
-rw-r--r-- | block/blk-core.c | 31 | ||||
-rw-r--r-- | include/linux/sched.h | 4 |
2 files changed, 16 insertions, 19 deletions
diff --git a/block/blk-core.c b/block/blk-core.c index 718897e6d37f..44b6d691728d 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
@@ -1490,9 +1490,9 @@ end_io: | |||
1490 | /* | 1490 | /* |
1491 | * We only want one ->make_request_fn to be active at a time, | 1491 | * We only want one ->make_request_fn to be active at a time, |
1492 | * else stack usage with stacked devices could be a problem. | 1492 | * else stack usage with stacked devices could be a problem. |
1493 | * So use current->bio_{list,tail} to keep a list of requests | 1493 | * So use current->bio_list to keep a list of requests |
1494 | * submited by a make_request_fn function. | 1494 | * submited by a make_request_fn function. |
1495 | * current->bio_tail is also used as a flag to say if | 1495 | * current->bio_list is also used as a flag to say if |
1496 | * generic_make_request is currently active in this task or not. | 1496 | * generic_make_request is currently active in this task or not. |
1497 | * If it is NULL, then no make_request is active. If it is non-NULL, | 1497 | * If it is NULL, then no make_request is active. If it is non-NULL, |
1498 | * then a make_request is active, and new requests should be added | 1498 | * then a make_request is active, and new requests should be added |
@@ -1500,11 +1500,11 @@ end_io: | |||
1500 | */ | 1500 | */ |
1501 | void generic_make_request(struct bio *bio) | 1501 | void generic_make_request(struct bio *bio) |
1502 | { | 1502 | { |
1503 | if (current->bio_tail) { | 1503 | struct bio_list bio_list_on_stack; |
1504 | |||
1505 | if (current->bio_list) { | ||
1504 | /* make_request is active */ | 1506 | /* make_request is active */ |
1505 | *(current->bio_tail) = bio; | 1507 | bio_list_add(current->bio_list, bio); |
1506 | bio->bi_next = NULL; | ||
1507 | current->bio_tail = &bio->bi_next; | ||
1508 | return; | 1508 | return; |
1509 | } | 1509 | } |
1510 | /* following loop may be a bit non-obvious, and so deserves some | 1510 | /* following loop may be a bit non-obvious, and so deserves some |
@@ -1512,30 +1512,27 @@ void generic_make_request(struct bio *bio) | |||
1512 | * Before entering the loop, bio->bi_next is NULL (as all callers | 1512 | * Before entering the loop, bio->bi_next is NULL (as all callers |
1513 | * ensure that) so we have a list with a single bio. | 1513 | * ensure that) so we have a list with a single bio. |
1514 | * We pretend that we have just taken it off a longer list, so | 1514 | * We pretend that we have just taken it off a longer list, so |
1515 | * we assign bio_list to the next (which is NULL) and bio_tail | 1515 | * we assign bio_list to a pointer to the bio_list_on_stack, |
1516 | * to &bio_list, thus initialising the bio_list of new bios to be | 1516 | * thus initialising the bio_list of new bios to be |
1517 | * added. __generic_make_request may indeed add some more bios | 1517 | * added. __generic_make_request may indeed add some more bios |
1518 | * through a recursive call to generic_make_request. If it | 1518 | * through a recursive call to generic_make_request. If it |
1519 | * did, we find a non-NULL value in bio_list and re-enter the loop | 1519 | * did, we find a non-NULL value in bio_list and re-enter the loop |
1520 | * from the top. In this case we really did just take the bio | 1520 | * from the top. In this case we really did just take the bio |
1521 | * of the top of the list (no pretending) and so fixup bio_list and | 1521 | * of the top of the list (no pretending) and so remove it from |
1522 | * bio_tail or bi_next, and call into __generic_make_request again. | 1522 | * bio_list, and call into __generic_make_request again. |
1523 | * | 1523 | * |
1524 | * The loop was structured like this to make only one call to | 1524 | * The loop was structured like this to make only one call to |
1525 | * __generic_make_request (which is important as it is large and | 1525 | * __generic_make_request (which is important as it is large and |
1526 | * inlined) and to keep the structure simple. | 1526 | * inlined) and to keep the structure simple. |
1527 | */ | 1527 | */ |
1528 | BUG_ON(bio->bi_next); | 1528 | BUG_ON(bio->bi_next); |
1529 | bio_list_init(&bio_list_on_stack); | ||
1530 | current->bio_list = &bio_list_on_stack; | ||
1529 | do { | 1531 | do { |
1530 | current->bio_list = bio->bi_next; | ||
1531 | if (bio->bi_next == NULL) | ||
1532 | current->bio_tail = ¤t->bio_list; | ||
1533 | else | ||
1534 | bio->bi_next = NULL; | ||
1535 | __generic_make_request(bio); | 1532 | __generic_make_request(bio); |
1536 | bio = current->bio_list; | 1533 | bio = bio_list_pop(current->bio_list); |
1537 | } while (bio); | 1534 | } while (bio); |
1538 | current->bio_tail = NULL; /* deactivate */ | 1535 | current->bio_list = NULL; /* deactivate */ |
1539 | } | 1536 | } |
1540 | EXPORT_SYMBOL(generic_make_request); | 1537 | EXPORT_SYMBOL(generic_make_request); |
1541 | 1538 | ||
diff --git a/include/linux/sched.h b/include/linux/sched.h index 78efe7c485ac..7eb82975e1ee 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -97,7 +97,7 @@ struct sched_param { | |||
97 | struct exec_domain; | 97 | struct exec_domain; |
98 | struct futex_pi_state; | 98 | struct futex_pi_state; |
99 | struct robust_list_head; | 99 | struct robust_list_head; |
100 | struct bio; | 100 | struct bio_list; |
101 | struct fs_struct; | 101 | struct fs_struct; |
102 | struct bts_context; | 102 | struct bts_context; |
103 | struct perf_event_context; | 103 | struct perf_event_context; |
@@ -1466,7 +1466,7 @@ struct task_struct { | |||
1466 | void *journal_info; | 1466 | void *journal_info; |
1467 | 1467 | ||
1468 | /* stacked block device info */ | 1468 | /* stacked block device info */ |
1469 | struct bio *bio_list, **bio_tail; | 1469 | struct bio_list *bio_list; |
1470 | 1470 | ||
1471 | /* VM state */ | 1471 | /* VM state */ |
1472 | struct reclaim_state *reclaim_state; | 1472 | struct reclaim_state *reclaim_state; |