diff options
author | Akinobu Mita <akinobu.mita@gmail.com> | 2010-02-24 02:30:08 -0500 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2010-02-24 02:30:08 -0500 |
commit | c5ecc484c528ff50bdbb16fbfbac758ee368b329 (patch) | |
tree | d0911df74db1d3828d5d885c178ce34ea30b7abd | |
parent | bddd87c7e622ea681c665049027ed84cdcafcb09 (diff) |
pktcdvd: use BIO list management functions
Now that the bio list management stuff is generic, convert pktcdvd to
use bio lists instead of its own private bio list implementation.
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Acked-by: Peter Osterlund <petero2@telia.com>
Cc: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r-- | drivers/block/pktcdvd.c | 89 | ||||
-rw-r--r-- | include/linux/pktcdvd.h | 10 |
2 files changed, 25 insertions, 74 deletions
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 68b5957f107c..7cd2973ebb7b 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -569,6 +569,7 @@ static struct packet_data *pkt_alloc_packet_data(int frames) | |||
569 | } | 569 | } |
570 | 570 | ||
571 | spin_lock_init(&pkt->lock); | 571 | spin_lock_init(&pkt->lock); |
572 | bio_list_init(&pkt->orig_bios); | ||
572 | 573 | ||
573 | for (i = 0; i < frames; i++) { | 574 | for (i = 0; i < frames; i++) { |
574 | struct bio *bio = pkt_bio_alloc(1); | 575 | struct bio *bio = pkt_bio_alloc(1); |
@@ -721,43 +722,6 @@ static void pkt_rbtree_insert(struct pktcdvd_device *pd, struct pkt_rb_node *nod | |||
721 | } | 722 | } |
722 | 723 | ||
723 | /* | 724 | /* |
724 | * Add a bio to a single linked list defined by its head and tail pointers. | ||
725 | */ | ||
726 | static void pkt_add_list_last(struct bio *bio, struct bio **list_head, struct bio **list_tail) | ||
727 | { | ||
728 | bio->bi_next = NULL; | ||
729 | if (*list_tail) { | ||
730 | BUG_ON((*list_head) == NULL); | ||
731 | (*list_tail)->bi_next = bio; | ||
732 | (*list_tail) = bio; | ||
733 | } else { | ||
734 | BUG_ON((*list_head) != NULL); | ||
735 | (*list_head) = bio; | ||
736 | (*list_tail) = bio; | ||
737 | } | ||
738 | } | ||
739 | |||
740 | /* | ||
741 | * Remove and return the first bio from a single linked list defined by its | ||
742 | * head and tail pointers. | ||
743 | */ | ||
744 | static inline struct bio *pkt_get_list_first(struct bio **list_head, struct bio **list_tail) | ||
745 | { | ||
746 | struct bio *bio; | ||
747 | |||
748 | if (*list_head == NULL) | ||
749 | return NULL; | ||
750 | |||
751 | bio = *list_head; | ||
752 | *list_head = bio->bi_next; | ||
753 | if (*list_head == NULL) | ||
754 | *list_tail = NULL; | ||
755 | |||
756 | bio->bi_next = NULL; | ||
757 | return bio; | ||
758 | } | ||
759 | |||
760 | /* | ||
761 | * Send a packet_command to the underlying block device and | 725 | * Send a packet_command to the underlying block device and |
762 | * wait for completion. | 726 | * wait for completion. |
763 | */ | 727 | */ |
@@ -876,13 +840,10 @@ static noinline_for_stack int pkt_set_speed(struct pktcdvd_device *pd, | |||
876 | static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio) | 840 | static void pkt_queue_bio(struct pktcdvd_device *pd, struct bio *bio) |
877 | { | 841 | { |
878 | spin_lock(&pd->iosched.lock); | 842 | spin_lock(&pd->iosched.lock); |
879 | if (bio_data_dir(bio) == READ) { | 843 | if (bio_data_dir(bio) == READ) |
880 | pkt_add_list_last(bio, &pd->iosched.read_queue, | 844 | bio_list_add(&pd->iosched.read_queue, bio); |
881 | &pd->iosched.read_queue_tail); | 845 | else |
882 | } else { | 846 | bio_list_add(&pd->iosched.write_queue, bio); |
883 | pkt_add_list_last(bio, &pd->iosched.write_queue, | ||
884 | &pd->iosched.write_queue_tail); | ||
885 | } | ||
886 | spin_unlock(&pd->iosched.lock); | 847 | spin_unlock(&pd->iosched.lock); |
887 | 848 | ||
888 | atomic_set(&pd->iosched.attention, 1); | 849 | atomic_set(&pd->iosched.attention, 1); |
@@ -917,8 +878,8 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd) | |||
917 | int reads_queued, writes_queued; | 878 | int reads_queued, writes_queued; |
918 | 879 | ||
919 | spin_lock(&pd->iosched.lock); | 880 | spin_lock(&pd->iosched.lock); |
920 | reads_queued = (pd->iosched.read_queue != NULL); | 881 | reads_queued = !bio_list_empty(&pd->iosched.read_queue); |
921 | writes_queued = (pd->iosched.write_queue != NULL); | 882 | writes_queued = !bio_list_empty(&pd->iosched.write_queue); |
922 | spin_unlock(&pd->iosched.lock); | 883 | spin_unlock(&pd->iosched.lock); |
923 | 884 | ||
924 | if (!reads_queued && !writes_queued) | 885 | if (!reads_queued && !writes_queued) |
@@ -927,7 +888,7 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd) | |||
927 | if (pd->iosched.writing) { | 888 | if (pd->iosched.writing) { |
928 | int need_write_seek = 1; | 889 | int need_write_seek = 1; |
929 | spin_lock(&pd->iosched.lock); | 890 | spin_lock(&pd->iosched.lock); |
930 | bio = pd->iosched.write_queue; | 891 | bio = bio_list_peek(&pd->iosched.write_queue); |
931 | spin_unlock(&pd->iosched.lock); | 892 | spin_unlock(&pd->iosched.lock); |
932 | if (bio && (bio->bi_sector == pd->iosched.last_write)) | 893 | if (bio && (bio->bi_sector == pd->iosched.last_write)) |
933 | need_write_seek = 0; | 894 | need_write_seek = 0; |
@@ -950,13 +911,10 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd) | |||
950 | } | 911 | } |
951 | 912 | ||
952 | spin_lock(&pd->iosched.lock); | 913 | spin_lock(&pd->iosched.lock); |
953 | if (pd->iosched.writing) { | 914 | if (pd->iosched.writing) |
954 | bio = pkt_get_list_first(&pd->iosched.write_queue, | 915 | bio = bio_list_pop(&pd->iosched.write_queue); |
955 | &pd->iosched.write_queue_tail); | 916 | else |
956 | } else { | 917 | bio = bio_list_pop(&pd->iosched.read_queue); |
957 | bio = pkt_get_list_first(&pd->iosched.read_queue, | ||
958 | &pd->iosched.read_queue_tail); | ||
959 | } | ||
960 | spin_unlock(&pd->iosched.lock); | 918 | spin_unlock(&pd->iosched.lock); |
961 | 919 | ||
962 | if (!bio) | 920 | if (!bio) |
@@ -1114,7 +1072,7 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt) | |||
1114 | int f; | 1072 | int f; |
1115 | char written[PACKET_MAX_SIZE]; | 1073 | char written[PACKET_MAX_SIZE]; |
1116 | 1074 | ||
1117 | BUG_ON(!pkt->orig_bios); | 1075 | BUG_ON(bio_list_empty(&pkt->orig_bios)); |
1118 | 1076 | ||
1119 | atomic_set(&pkt->io_wait, 0); | 1077 | atomic_set(&pkt->io_wait, 0); |
1120 | atomic_set(&pkt->io_errors, 0); | 1078 | atomic_set(&pkt->io_errors, 0); |
@@ -1124,7 +1082,7 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt) | |||
1124 | */ | 1082 | */ |
1125 | memset(written, 0, sizeof(written)); | 1083 | memset(written, 0, sizeof(written)); |
1126 | spin_lock(&pkt->lock); | 1084 | spin_lock(&pkt->lock); |
1127 | for (bio = pkt->orig_bios; bio; bio = bio->bi_next) { | 1085 | bio_list_for_each(bio, &pkt->orig_bios) { |
1128 | int first_frame = (bio->bi_sector - pkt->sector) / (CD_FRAMESIZE >> 9); | 1086 | int first_frame = (bio->bi_sector - pkt->sector) / (CD_FRAMESIZE >> 9); |
1129 | int num_frames = bio->bi_size / CD_FRAMESIZE; | 1087 | int num_frames = bio->bi_size / CD_FRAMESIZE; |
1130 | pd->stats.secs_w += num_frames * (CD_FRAMESIZE >> 9); | 1088 | pd->stats.secs_w += num_frames * (CD_FRAMESIZE >> 9); |
@@ -1363,7 +1321,7 @@ try_next_bio: | |||
1363 | break; | 1321 | break; |
1364 | pkt_rbtree_erase(pd, node); | 1322 | pkt_rbtree_erase(pd, node); |
1365 | spin_lock(&pkt->lock); | 1323 | spin_lock(&pkt->lock); |
1366 | pkt_add_list_last(bio, &pkt->orig_bios, &pkt->orig_bios_tail); | 1324 | bio_list_add(&pkt->orig_bios, bio); |
1367 | pkt->write_size += bio->bi_size / CD_FRAMESIZE; | 1325 | pkt->write_size += bio->bi_size / CD_FRAMESIZE; |
1368 | spin_unlock(&pkt->lock); | 1326 | spin_unlock(&pkt->lock); |
1369 | } | 1327 | } |
@@ -1409,7 +1367,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) | |||
1409 | */ | 1367 | */ |
1410 | frames_write = 0; | 1368 | frames_write = 0; |
1411 | spin_lock(&pkt->lock); | 1369 | spin_lock(&pkt->lock); |
1412 | for (bio = pkt->orig_bios; bio; bio = bio->bi_next) { | 1370 | bio_list_for_each(bio, &pkt->orig_bios) { |
1413 | int segment = bio->bi_idx; | 1371 | int segment = bio->bi_idx; |
1414 | int src_offs = 0; | 1372 | int src_offs = 0; |
1415 | int first_frame = (bio->bi_sector - pkt->sector) / (CD_FRAMESIZE >> 9); | 1373 | int first_frame = (bio->bi_sector - pkt->sector) / (CD_FRAMESIZE >> 9); |
@@ -1472,20 +1430,14 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) | |||
1472 | 1430 | ||
1473 | static void pkt_finish_packet(struct packet_data *pkt, int uptodate) | 1431 | static void pkt_finish_packet(struct packet_data *pkt, int uptodate) |
1474 | { | 1432 | { |
1475 | struct bio *bio, *next; | 1433 | struct bio *bio; |
1476 | 1434 | ||
1477 | if (!uptodate) | 1435 | if (!uptodate) |
1478 | pkt->cache_valid = 0; | 1436 | pkt->cache_valid = 0; |
1479 | 1437 | ||
1480 | /* Finish all bios corresponding to this packet */ | 1438 | /* Finish all bios corresponding to this packet */ |
1481 | bio = pkt->orig_bios; | 1439 | while ((bio = bio_list_pop(&pkt->orig_bios))) |
1482 | while (bio) { | ||
1483 | next = bio->bi_next; | ||
1484 | bio->bi_next = NULL; | ||
1485 | bio_endio(bio, uptodate ? 0 : -EIO); | 1440 | bio_endio(bio, uptodate ? 0 : -EIO); |
1486 | bio = next; | ||
1487 | } | ||
1488 | pkt->orig_bios = pkt->orig_bios_tail = NULL; | ||
1489 | } | 1441 | } |
1490 | 1442 | ||
1491 | static void pkt_run_state_machine(struct pktcdvd_device *pd, struct packet_data *pkt) | 1443 | static void pkt_run_state_machine(struct pktcdvd_device *pd, struct packet_data *pkt) |
@@ -2567,8 +2519,7 @@ static int pkt_make_request(struct request_queue *q, struct bio *bio) | |||
2567 | spin_lock(&pkt->lock); | 2519 | spin_lock(&pkt->lock); |
2568 | if ((pkt->state == PACKET_WAITING_STATE) || | 2520 | if ((pkt->state == PACKET_WAITING_STATE) || |
2569 | (pkt->state == PACKET_READ_WAIT_STATE)) { | 2521 | (pkt->state == PACKET_READ_WAIT_STATE)) { |
2570 | pkt_add_list_last(bio, &pkt->orig_bios, | 2522 | bio_list_add(&pkt->orig_bios, bio); |
2571 | &pkt->orig_bios_tail); | ||
2572 | pkt->write_size += bio->bi_size / CD_FRAMESIZE; | 2523 | pkt->write_size += bio->bi_size / CD_FRAMESIZE; |
2573 | if ((pkt->write_size >= pkt->frames) && | 2524 | if ((pkt->write_size >= pkt->frames) && |
2574 | (pkt->state == PACKET_WAITING_STATE)) { | 2525 | (pkt->state == PACKET_WAITING_STATE)) { |
@@ -2898,6 +2849,8 @@ static int pkt_setup_dev(dev_t dev, dev_t* pkt_dev) | |||
2898 | 2849 | ||
2899 | spin_lock_init(&pd->lock); | 2850 | spin_lock_init(&pd->lock); |
2900 | spin_lock_init(&pd->iosched.lock); | 2851 | spin_lock_init(&pd->iosched.lock); |
2852 | bio_list_init(&pd->iosched.read_queue); | ||
2853 | bio_list_init(&pd->iosched.write_queue); | ||
2901 | sprintf(pd->name, DRIVER_NAME"%d", idx); | 2854 | sprintf(pd->name, DRIVER_NAME"%d", idx); |
2902 | init_waitqueue_head(&pd->wqueue); | 2855 | init_waitqueue_head(&pd->wqueue); |
2903 | pd->bio_queue = RB_ROOT; | 2856 | pd->bio_queue = RB_ROOT; |
diff --git a/include/linux/pktcdvd.h b/include/linux/pktcdvd.h index 76e5053e1fac..721301b0a908 100644 --- a/include/linux/pktcdvd.h +++ b/include/linux/pktcdvd.h | |||
@@ -163,10 +163,8 @@ struct packet_iosched | |||
163 | atomic_t attention; /* Set to non-zero when queue processing is needed */ | 163 | atomic_t attention; /* Set to non-zero when queue processing is needed */ |
164 | int writing; /* Non-zero when writing, zero when reading */ | 164 | int writing; /* Non-zero when writing, zero when reading */ |
165 | spinlock_t lock; /* Protecting read/write queue manipulations */ | 165 | spinlock_t lock; /* Protecting read/write queue manipulations */ |
166 | struct bio *read_queue; | 166 | struct bio_list read_queue; |
167 | struct bio *read_queue_tail; | 167 | struct bio_list write_queue; |
168 | struct bio *write_queue; | ||
169 | struct bio *write_queue_tail; | ||
170 | sector_t last_write; /* The sector where the last write ended */ | 168 | sector_t last_write; /* The sector where the last write ended */ |
171 | int successive_reads; | 169 | int successive_reads; |
172 | }; | 170 | }; |
@@ -206,8 +204,8 @@ struct packet_data | |||
206 | spinlock_t lock; /* Lock protecting state transitions and */ | 204 | spinlock_t lock; /* Lock protecting state transitions and */ |
207 | /* orig_bios list */ | 205 | /* orig_bios list */ |
208 | 206 | ||
209 | struct bio *orig_bios; /* Original bios passed to pkt_make_request */ | 207 | struct bio_list orig_bios; /* Original bios passed to pkt_make_request */ |
210 | struct bio *orig_bios_tail;/* that will be handled by this packet */ | 208 | /* that will be handled by this packet */ |
211 | int write_size; /* Total size of all bios in the orig_bios */ | 209 | int write_size; /* Total size of all bios in the orig_bios */ |
212 | /* list, measured in number of frames */ | 210 | /* list, measured in number of frames */ |
213 | 211 | ||