aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/pktcdvd.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-08 13:13:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-08 13:13:35 -0400
commit4de13d7aa8f4d02f4dc99d4609575659f92b3c5a (patch)
tree3bc9729eabe79c6164cd29a5d605000bc82bf837 /drivers/block/pktcdvd.c
parent5af43c24ca59a448c9312dd4a4a51d27ec3b9a73 (diff)
parentb8d4a5bf6a049303a29a3275f463f09a490b50ea (diff)
Merge branch 'for-3.10/core' of git://git.kernel.dk/linux-block
Pull block core updates from Jens Axboe: - Major bit is Kents prep work for immutable bio vecs. - Stable candidate fix for a scheduling-while-atomic in the queue bypass operation. - Fix for the hang on exceeded rq->datalen 32-bit unsigned when merging discard bios. - Tejuns changes to convert the writeback thread pool to the generic workqueue mechanism. - Runtime PM framework, SCSI patches exists on top of these in James' tree. - A few random fixes. * 'for-3.10/core' of git://git.kernel.dk/linux-block: (40 commits) relay: move remove_buf_file inside relay_close_buf partitions/efi.c: replace useless kzalloc's by kmalloc's fs/block_dev.c: fix iov_shorten() criteria in blkdev_aio_read() block: fix max discard sectors limit blkcg: fix "scheduling while atomic" in blk_queue_bypass_start Documentation: cfq-iosched: update documentation help for cfq tunables writeback: expose the bdi_wq workqueue writeback: replace custom worker pool implementation with unbound workqueue writeback: remove unused bdi_pending_list aoe: Fix unitialized var usage bio-integrity: Add explicit field for owner of bip_buf block: Add an explicit bio flag for bios that own their bvec block: Add bio_alloc_pages() block: Convert some code to bio_for_each_segment_all() block: Add bio_for_each_segment_all() bounce: Refactor __blk_queue_bounce to not use bi_io_vec raid1: use bio_copy_data() pktcdvd: Use bio_reset() in disabled code to kill bi_idx usage pktcdvd: use bio_copy_data() block: Add bio_copy_data() ...
Diffstat (limited to 'drivers/block/pktcdvd.c')
-rw-r--r--drivers/block/pktcdvd.c102
1 files changed, 23 insertions, 79 deletions
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 9f2d348f7115..3c08983e600a 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -901,7 +901,7 @@ static void pkt_iosched_process_queue(struct pktcdvd_device *pd)
901 pd->iosched.successive_reads += bio->bi_size >> 10; 901 pd->iosched.successive_reads += bio->bi_size >> 10;
902 else { 902 else {
903 pd->iosched.successive_reads = 0; 903 pd->iosched.successive_reads = 0;
904 pd->iosched.last_write = bio->bi_sector + bio_sectors(bio); 904 pd->iosched.last_write = bio_end_sector(bio);
905 } 905 }
906 if (pd->iosched.successive_reads >= HI_SPEED_SWITCH) { 906 if (pd->iosched.successive_reads >= HI_SPEED_SWITCH) {
907 if (pd->read_speed == pd->write_speed) { 907 if (pd->read_speed == pd->write_speed) {
@@ -948,31 +948,6 @@ static int pkt_set_segment_merging(struct pktcdvd_device *pd, struct request_que
948} 948}
949 949
950/* 950/*
951 * Copy CD_FRAMESIZE bytes from src_bio into a destination page
952 */
953static void pkt_copy_bio_data(struct bio *src_bio, int seg, int offs, struct page *dst_page, int dst_offs)
954{
955 unsigned int copy_size = CD_FRAMESIZE;
956
957 while (copy_size > 0) {
958 struct bio_vec *src_bvl = bio_iovec_idx(src_bio, seg);
959 void *vfrom = kmap_atomic(src_bvl->bv_page) +
960 src_bvl->bv_offset + offs;
961 void *vto = page_address(dst_page) + dst_offs;
962 int len = min_t(int, copy_size, src_bvl->bv_len - offs);
963
964 BUG_ON(len < 0);
965 memcpy(vto, vfrom, len);
966 kunmap_atomic(vfrom);
967
968 seg++;
969 offs = 0;
970 dst_offs += len;
971 copy_size -= len;
972 }
973}
974
975/*
976 * Copy all data for this packet to pkt->pages[], so that 951 * Copy all data for this packet to pkt->pages[], so that
977 * a) The number of required segments for the write bio is minimized, which 952 * a) The number of required segments for the write bio is minimized, which
978 * is necessary for some scsi controllers. 953 * is necessary for some scsi controllers.
@@ -1181,16 +1156,15 @@ static int pkt_start_recovery(struct packet_data *pkt)
1181 new_sector = new_block * (CD_FRAMESIZE >> 9); 1156 new_sector = new_block * (CD_FRAMESIZE >> 9);
1182 pkt->sector = new_sector; 1157 pkt->sector = new_sector;
1183 1158
1159 bio_reset(pkt->bio);
1160 pkt->bio->bi_bdev = pd->bdev;
1161 pkt->bio->bi_rw = REQ_WRITE;
1184 pkt->bio->bi_sector = new_sector; 1162 pkt->bio->bi_sector = new_sector;
1185 pkt->bio->bi_next = NULL; 1163 pkt->bio->bi_size = pkt->frames * CD_FRAMESIZE;
1186 pkt->bio->bi_flags = 1 << BIO_UPTODATE; 1164 pkt->bio->bi_vcnt = pkt->frames;
1187 pkt->bio->bi_idx = 0;
1188 1165
1189 BUG_ON(pkt->bio->bi_rw != REQ_WRITE); 1166 pkt->bio->bi_end_io = pkt_end_io_packet_write;
1190 BUG_ON(pkt->bio->bi_vcnt != pkt->frames); 1167 pkt->bio->bi_private = pkt;
1191 BUG_ON(pkt->bio->bi_size != pkt->frames * CD_FRAMESIZE);
1192 BUG_ON(pkt->bio->bi_end_io != pkt_end_io_packet_write);
1193 BUG_ON(pkt->bio->bi_private != pkt);
1194 1168
1195 drop_super(sb); 1169 drop_super(sb);
1196 return 1; 1170 return 1;
@@ -1325,55 +1299,35 @@ try_next_bio:
1325 */ 1299 */
1326static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) 1300static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
1327{ 1301{
1328 struct bio *bio;
1329 int f; 1302 int f;
1330 int frames_write;
1331 struct bio_vec *bvec = pkt->w_bio->bi_io_vec; 1303 struct bio_vec *bvec = pkt->w_bio->bi_io_vec;
1332 1304
1305 bio_reset(pkt->w_bio);
1306 pkt->w_bio->bi_sector = pkt->sector;
1307 pkt->w_bio->bi_bdev = pd->bdev;
1308 pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
1309 pkt->w_bio->bi_private = pkt;
1310
1311 /* XXX: locking? */
1333 for (f = 0; f < pkt->frames; f++) { 1312 for (f = 0; f < pkt->frames; f++) {
1334 bvec[f].bv_page = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE]; 1313 bvec[f].bv_page = pkt->pages[(f * CD_FRAMESIZE) / PAGE_SIZE];
1335 bvec[f].bv_offset = (f * CD_FRAMESIZE) % PAGE_SIZE; 1314 bvec[f].bv_offset = (f * CD_FRAMESIZE) % PAGE_SIZE;
1315 if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset))
1316 BUG();
1336 } 1317 }
1318 VPRINTK(DRIVER_NAME": vcnt=%d\n", pkt->w_bio->bi_vcnt);
1337 1319
1338 /* 1320 /*
1339 * Fill-in bvec with data from orig_bios. 1321 * Fill-in bvec with data from orig_bios.
1340 */ 1322 */
1341 frames_write = 0;
1342 spin_lock(&pkt->lock); 1323 spin_lock(&pkt->lock);
1343 bio_list_for_each(bio, &pkt->orig_bios) { 1324 bio_copy_data(pkt->w_bio, pkt->orig_bios.head);
1344 int segment = bio->bi_idx;
1345 int src_offs = 0;
1346 int first_frame = (bio->bi_sector - pkt->sector) / (CD_FRAMESIZE >> 9);
1347 int num_frames = bio->bi_size / CD_FRAMESIZE;
1348 BUG_ON(first_frame < 0);
1349 BUG_ON(first_frame + num_frames > pkt->frames);
1350 for (f = first_frame; f < first_frame + num_frames; f++) {
1351 struct bio_vec *src_bvl = bio_iovec_idx(bio, segment);
1352
1353 while (src_offs >= src_bvl->bv_len) {
1354 src_offs -= src_bvl->bv_len;
1355 segment++;
1356 BUG_ON(segment >= bio->bi_vcnt);
1357 src_bvl = bio_iovec_idx(bio, segment);
1358 }
1359 1325
1360 if (src_bvl->bv_len - src_offs >= CD_FRAMESIZE) {
1361 bvec[f].bv_page = src_bvl->bv_page;
1362 bvec[f].bv_offset = src_bvl->bv_offset + src_offs;
1363 } else {
1364 pkt_copy_bio_data(bio, segment, src_offs,
1365 bvec[f].bv_page, bvec[f].bv_offset);
1366 }
1367 src_offs += CD_FRAMESIZE;
1368 frames_write++;
1369 }
1370 }
1371 pkt_set_state(pkt, PACKET_WRITE_WAIT_STATE); 1326 pkt_set_state(pkt, PACKET_WRITE_WAIT_STATE);
1372 spin_unlock(&pkt->lock); 1327 spin_unlock(&pkt->lock);
1373 1328
1374 VPRINTK("pkt_start_write: Writing %d frames for zone %llx\n", 1329 VPRINTK("pkt_start_write: Writing %d frames for zone %llx\n",
1375 frames_write, (unsigned long long)pkt->sector); 1330 pkt->write_size, (unsigned long long)pkt->sector);
1376 BUG_ON(frames_write != pkt->write_size);
1377 1331
1378 if (test_bit(PACKET_MERGE_SEGS, &pd->flags) || (pkt->write_size < pkt->frames)) { 1332 if (test_bit(PACKET_MERGE_SEGS, &pd->flags) || (pkt->write_size < pkt->frames)) {
1379 pkt_make_local_copy(pkt, bvec); 1333 pkt_make_local_copy(pkt, bvec);
@@ -1383,16 +1337,6 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
1383 } 1337 }
1384 1338
1385 /* Start the write request */ 1339 /* Start the write request */
1386 bio_reset(pkt->w_bio);
1387 pkt->w_bio->bi_sector = pkt->sector;
1388 pkt->w_bio->bi_bdev = pd->bdev;
1389 pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
1390 pkt->w_bio->bi_private = pkt;
1391 for (f = 0; f < pkt->frames; f++)
1392 if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset))
1393 BUG();
1394 VPRINTK(DRIVER_NAME": vcnt=%d\n", pkt->w_bio->bi_vcnt);
1395
1396 atomic_set(&pkt->io_wait, 1); 1340 atomic_set(&pkt->io_wait, 1);
1397 pkt->w_bio->bi_rw = WRITE; 1341 pkt->w_bio->bi_rw = WRITE;
1398 pkt_queue_bio(pd, pkt->w_bio); 1342 pkt_queue_bio(pd, pkt->w_bio);
@@ -2431,7 +2375,7 @@ static void pkt_make_request(struct request_queue *q, struct bio *bio)
2431 cloned_bio->bi_bdev = pd->bdev; 2375 cloned_bio->bi_bdev = pd->bdev;
2432 cloned_bio->bi_private = psd; 2376 cloned_bio->bi_private = psd;
2433 cloned_bio->bi_end_io = pkt_end_io_read_cloned; 2377 cloned_bio->bi_end_io = pkt_end_io_read_cloned;
2434 pd->stats.secs_r += bio->bi_size >> 9; 2378 pd->stats.secs_r += bio_sectors(bio);
2435 pkt_queue_bio(pd, cloned_bio); 2379 pkt_queue_bio(pd, cloned_bio);
2436 return; 2380 return;
2437 } 2381 }
@@ -2452,7 +2396,7 @@ static void pkt_make_request(struct request_queue *q, struct bio *bio)
2452 zone = ZONE(bio->bi_sector, pd); 2396 zone = ZONE(bio->bi_sector, pd);
2453 VPRINTK("pkt_make_request: start = %6llx stop = %6llx\n", 2397 VPRINTK("pkt_make_request: start = %6llx stop = %6llx\n",
2454 (unsigned long long)bio->bi_sector, 2398 (unsigned long long)bio->bi_sector,
2455 (unsigned long long)(bio->bi_sector + bio_sectors(bio))); 2399 (unsigned long long)bio_end_sector(bio));
2456 2400
2457 /* Check if we have to split the bio */ 2401 /* Check if we have to split the bio */
2458 { 2402 {
@@ -2460,7 +2404,7 @@ static void pkt_make_request(struct request_queue *q, struct bio *bio)
2460 sector_t last_zone; 2404 sector_t last_zone;
2461 int first_sectors; 2405 int first_sectors;
2462 2406
2463 last_zone = ZONE(bio->bi_sector + bio_sectors(bio) - 1, pd); 2407 last_zone = ZONE(bio_end_sector(bio) - 1, pd);
2464 if (last_zone != zone) { 2408 if (last_zone != zone) {
2465 BUG_ON(last_zone != zone + pd->settings.size); 2409 BUG_ON(last_zone != zone + pd->settings.size);
2466 first_sectors = last_zone - bio->bi_sector; 2410 first_sectors = last_zone - bio->bi_sector;