aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/pktcdvd.c43
1 files changed, 17 insertions, 26 deletions
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 89d8fe014efa..93e44d0292ab 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -645,7 +645,7 @@ static void pkt_copy_bio_data(struct bio *src_bio, int seg, int offs, struct pag
645 * b) The data can be used as cache to avoid read requests if we receive a 645 * b) The data can be used as cache to avoid read requests if we receive a
646 * new write request for the same zone. 646 * new write request for the same zone.
647 */ 647 */
648static void pkt_make_local_copy(struct packet_data *pkt, struct page **pages, int *offsets) 648static void pkt_make_local_copy(struct packet_data *pkt, struct bio_vec *bvec)
649{ 649{
650 int f, p, offs; 650 int f, p, offs;
651 651
@@ -653,15 +653,15 @@ static void pkt_make_local_copy(struct packet_data *pkt, struct page **pages, in
653 p = 0; 653 p = 0;
654 offs = 0; 654 offs = 0;
655 for (f = 0; f < pkt->frames; f++) { 655 for (f = 0; f < pkt->frames; f++) {
656 if (pages[f] != pkt->pages[p]) { 656 if (bvec[f].bv_page != pkt->pages[p]) {
657 void *vfrom = kmap_atomic(pages[f], KM_USER0) + offsets[f]; 657 void *vfrom = kmap_atomic(bvec[f].bv_page, KM_USER0) + bvec[f].bv_offset;
658 void *vto = page_address(pkt->pages[p]) + offs; 658 void *vto = page_address(pkt->pages[p]) + offs;
659 memcpy(vto, vfrom, CD_FRAMESIZE); 659 memcpy(vto, vfrom, CD_FRAMESIZE);
660 kunmap_atomic(vfrom, KM_USER0); 660 kunmap_atomic(vfrom, KM_USER0);
661 pages[f] = pkt->pages[p]; 661 bvec[f].bv_page = pkt->pages[p];
662 offsets[f] = offs; 662 bvec[f].bv_offset = offs;
663 } else { 663 } else {
664 BUG_ON(offsets[f] != offs); 664 BUG_ON(bvec[f].bv_offset != offs);
665 } 665 }
666 offs += CD_FRAMESIZE; 666 offs += CD_FRAMESIZE;
667 if (offs >= PAGE_SIZE) { 667 if (offs >= PAGE_SIZE) {
@@ -991,18 +991,17 @@ try_next_bio:
991static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) 991static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
992{ 992{
993 struct bio *bio; 993 struct bio *bio;
994 struct page *pages[PACKET_MAX_SIZE];
995 int offsets[PACKET_MAX_SIZE];
996 int f; 994 int f;
997 int frames_write; 995 int frames_write;
996 struct bio_vec *bvec = pkt->w_bio->bi_io_vec;
998 997
999 for (f = 0; f < pkt->frames; f++) { 998 for (f = 0; f < pkt->frames; f++) {
1000 pages[f] = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE]; 999 bvec[f].bv_page = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE];
1001 offsets[f] = (f * CD_FRAMESIZE) % PAGE_SIZE; 1000 bvec[f].bv_offset = (f * CD_FRAMESIZE) % PAGE_SIZE;
1002 } 1001 }
1003 1002
1004 /* 1003 /*
1005 * Fill-in pages[] and offsets[] with data from orig_bios. 1004 * Fill-in bvec with data from orig_bios.
1006 */ 1005 */
1007 frames_write = 0; 1006 frames_write = 0;
1008 spin_lock(&pkt->lock); 1007 spin_lock(&pkt->lock);
@@ -1024,11 +1023,11 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
1024 } 1023 }
1025 1024
1026 if (src_bvl->bv_len - src_offs >= CD_FRAMESIZE) { 1025 if (src_bvl->bv_len - src_offs >= CD_FRAMESIZE) {
1027 pages[f] = src_bvl->bv_page; 1026 bvec[f].bv_page = src_bvl->bv_page;
1028 offsets[f] = src_bvl->bv_offset + src_offs; 1027 bvec[f].bv_offset = src_bvl->bv_offset + src_offs;
1029 } else { 1028 } else {
1030 pkt_copy_bio_data(bio, segment, src_offs, 1029 pkt_copy_bio_data(bio, segment, src_offs,
1031 pages[f], offsets[f]); 1030 bvec[f].bv_page, bvec[f].bv_offset);
1032 } 1031 }
1033 src_offs += CD_FRAMESIZE; 1032 src_offs += CD_FRAMESIZE;
1034 frames_write++; 1033 frames_write++;
@@ -1042,7 +1041,7 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
1042 BUG_ON(frames_write != pkt->write_size); 1041 BUG_ON(frames_write != pkt->write_size);
1043 1042
1044 if (test_bit(PACKET_MERGE_SEGS, &pd->flags) || (pkt->write_size < pkt->frames)) { 1043 if (test_bit(PACKET_MERGE_SEGS, &pd->flags) || (pkt->write_size < pkt->frames)) {
1045 pkt_make_local_copy(pkt, pages, offsets); 1044 pkt_make_local_copy(pkt, bvec);
1046 pkt->cache_valid = 1; 1045 pkt->cache_valid = 1;
1047 } else { 1046 } else {
1048 pkt->cache_valid = 0; 1047 pkt->cache_valid = 0;
@@ -1055,17 +1054,9 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
1055 pkt->w_bio->bi_bdev = pd->bdev; 1054 pkt->w_bio->bi_bdev = pd->bdev;
1056 pkt->w_bio->bi_end_io = pkt_end_io_packet_write; 1055 pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
1057 pkt->w_bio->bi_private = pkt; 1056 pkt->w_bio->bi_private = pkt;
1058 for (f = 0; f < pkt->frames; f++) { 1057 for (f = 0; f < pkt->frames; f++)
1059 if ((f + 1 < pkt->frames) && (pages[f + 1] == pages[f]) && 1058 if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset))
1060 (offsets[f + 1] = offsets[f] + CD_FRAMESIZE)) { 1059 BUG();
1061 if (!bio_add_page(pkt->w_bio, pages[f], CD_FRAMESIZE * 2, offsets[f]))
1062 BUG();
1063 f++;
1064 } else {
1065 if (!bio_add_page(pkt->w_bio, pages[f], CD_FRAMESIZE, offsets[f]))
1066 BUG();
1067 }
1068 }
1069 VPRINTK("pktcdvd: vcnt=%d\n", pkt->w_bio->bi_vcnt); 1060 VPRINTK("pktcdvd: vcnt=%d\n", pkt->w_bio->bi_vcnt);
1070 1061
1071 atomic_set(&pkt->io_wait, 1); 1062 atomic_set(&pkt->io_wait, 1);