diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-08 13:13:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-08 13:13:35 -0400 |
commit | 4de13d7aa8f4d02f4dc99d4609575659f92b3c5a (patch) | |
tree | 3bc9729eabe79c6164cd29a5d605000bc82bf837 /drivers/block/pktcdvd.c | |
parent | 5af43c24ca59a448c9312dd4a4a51d27ec3b9a73 (diff) | |
parent | b8d4a5bf6a049303a29a3275f463f09a490b50ea (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.c | 102 |
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 | */ | ||
953 | static 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 | */ |
1326 | static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt) | 1300 | static 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; |