diff options
author | Kent Overstreet <kmo@daterainc.com> | 2013-11-23 21:21:01 -0500 |
---|---|---|
committer | Kent Overstreet <kmo@daterainc.com> | 2013-11-24 01:33:57 -0500 |
commit | 20d0189b1012a37d2533a87fb451f7852f2418d1 (patch) | |
tree | 5ceaa6cfc0e1f1cec423c6c9f5de72d49f2d63a1 /drivers/block/pktcdvd.c | |
parent | ee67891bf132612feb7b999ee1f3350b40867cb4 (diff) |
block: Introduce new bio_split()
The new bio_split() can split arbitrary bios - it's not restricted to
single page bios, like the old bio_split() (previously renamed to
bio_pair_split()). It also has different semantics - it doesn't allocate
a struct bio_pair, leaving it up to the caller to handle completions.
Then convert the existing bio_pair_split() users to the new bio_split()
- and also nvme, which was open coding bio splitting.
(We have to take that BUG_ON() out of bio_integrity_trim() because this
bio_split() needs to use it, and there's no reason it has to be used on
bios marked as cloned; BIO_CLONED doesn't seem to have clearly
documented semantics anyways.)
Signed-off-by: Kent Overstreet <kmo@daterainc.com>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Martin K. Petersen <martin.petersen@oracle.com>
Cc: Matthew Wilcox <matthew.r.wilcox@intel.com>
Cc: Keith Busch <keith.busch@intel.com>
Cc: Vishal Verma <vishal.l.verma@intel.com>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Neil Brown <neilb@suse.de>
Diffstat (limited to 'drivers/block/pktcdvd.c')
-rw-r--r-- | drivers/block/pktcdvd.c | 136 |
1 files changed, 74 insertions, 62 deletions
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 28789b82ae7d..3dda09a5ec41 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -2338,75 +2338,29 @@ static void pkt_end_io_read_cloned(struct bio *bio, int err) | |||
2338 | pkt_bio_finished(pd); | 2338 | pkt_bio_finished(pd); |
2339 | } | 2339 | } |
2340 | 2340 | ||
2341 | static void pkt_make_request(struct request_queue *q, struct bio *bio) | 2341 | static void pkt_make_request_read(struct pktcdvd_device *pd, struct bio *bio) |
2342 | { | 2342 | { |
2343 | struct pktcdvd_device *pd; | 2343 | struct bio *cloned_bio = bio_clone(bio, GFP_NOIO); |
2344 | char b[BDEVNAME_SIZE]; | 2344 | struct packet_stacked_data *psd = mempool_alloc(psd_pool, GFP_NOIO); |
2345 | |||
2346 | psd->pd = pd; | ||
2347 | psd->bio = bio; | ||
2348 | cloned_bio->bi_bdev = pd->bdev; | ||
2349 | cloned_bio->bi_private = psd; | ||
2350 | cloned_bio->bi_end_io = pkt_end_io_read_cloned; | ||
2351 | pd->stats.secs_r += bio_sectors(bio); | ||
2352 | pkt_queue_bio(pd, cloned_bio); | ||
2353 | } | ||
2354 | |||
2355 | static void pkt_make_request_write(struct request_queue *q, struct bio *bio) | ||
2356 | { | ||
2357 | struct pktcdvd_device *pd = q->queuedata; | ||
2345 | sector_t zone; | 2358 | sector_t zone; |
2346 | struct packet_data *pkt; | 2359 | struct packet_data *pkt; |
2347 | int was_empty, blocked_bio; | 2360 | int was_empty, blocked_bio; |
2348 | struct pkt_rb_node *node; | 2361 | struct pkt_rb_node *node; |
2349 | 2362 | ||
2350 | pd = q->queuedata; | ||
2351 | if (!pd) { | ||
2352 | pr_err("%s incorrect request queue\n", | ||
2353 | bdevname(bio->bi_bdev, b)); | ||
2354 | goto end_io; | ||
2355 | } | ||
2356 | |||
2357 | /* | ||
2358 | * Clone READ bios so we can have our own bi_end_io callback. | ||
2359 | */ | ||
2360 | if (bio_data_dir(bio) == READ) { | ||
2361 | struct bio *cloned_bio = bio_clone(bio, GFP_NOIO); | ||
2362 | struct packet_stacked_data *psd = mempool_alloc(psd_pool, GFP_NOIO); | ||
2363 | |||
2364 | psd->pd = pd; | ||
2365 | psd->bio = bio; | ||
2366 | cloned_bio->bi_bdev = pd->bdev; | ||
2367 | cloned_bio->bi_private = psd; | ||
2368 | cloned_bio->bi_end_io = pkt_end_io_read_cloned; | ||
2369 | pd->stats.secs_r += bio_sectors(bio); | ||
2370 | pkt_queue_bio(pd, cloned_bio); | ||
2371 | return; | ||
2372 | } | ||
2373 | |||
2374 | if (!test_bit(PACKET_WRITABLE, &pd->flags)) { | ||
2375 | pkt_notice(pd, "WRITE for ro device (%llu)\n", | ||
2376 | (unsigned long long)bio->bi_iter.bi_sector); | ||
2377 | goto end_io; | ||
2378 | } | ||
2379 | |||
2380 | if (!bio->bi_iter.bi_size || (bio->bi_iter.bi_size % CD_FRAMESIZE)) { | ||
2381 | pkt_err(pd, "wrong bio size\n"); | ||
2382 | goto end_io; | ||
2383 | } | ||
2384 | |||
2385 | blk_queue_bounce(q, &bio); | ||
2386 | |||
2387 | zone = get_zone(bio->bi_iter.bi_sector, pd); | 2363 | zone = get_zone(bio->bi_iter.bi_sector, pd); |
2388 | pkt_dbg(2, pd, "start = %6llx stop = %6llx\n", | ||
2389 | (unsigned long long)bio->bi_iter.bi_sector, | ||
2390 | (unsigned long long)bio_end_sector(bio)); | ||
2391 | |||
2392 | /* Check if we have to split the bio */ | ||
2393 | { | ||
2394 | struct bio_pair *bp; | ||
2395 | sector_t last_zone; | ||
2396 | int first_sectors; | ||
2397 | |||
2398 | last_zone = get_zone(bio_end_sector(bio) - 1, pd); | ||
2399 | if (last_zone != zone) { | ||
2400 | BUG_ON(last_zone != zone + pd->settings.size); | ||
2401 | first_sectors = last_zone - bio->bi_iter.bi_sector; | ||
2402 | bp = bio_pair_split(bio, first_sectors); | ||
2403 | BUG_ON(!bp); | ||
2404 | pkt_make_request(q, &bp->bio1); | ||
2405 | pkt_make_request(q, &bp->bio2); | ||
2406 | bio_pair_release(bp); | ||
2407 | return; | ||
2408 | } | ||
2409 | } | ||
2410 | 2364 | ||
2411 | /* | 2365 | /* |
2412 | * If we find a matching packet in state WAITING or READ_WAIT, we can | 2366 | * If we find a matching packet in state WAITING or READ_WAIT, we can |
@@ -2480,6 +2434,64 @@ static void pkt_make_request(struct request_queue *q, struct bio *bio) | |||
2480 | */ | 2434 | */ |
2481 | wake_up(&pd->wqueue); | 2435 | wake_up(&pd->wqueue); |
2482 | } | 2436 | } |
2437 | } | ||
2438 | |||
2439 | static void pkt_make_request(struct request_queue *q, struct bio *bio) | ||
2440 | { | ||
2441 | struct pktcdvd_device *pd; | ||
2442 | char b[BDEVNAME_SIZE]; | ||
2443 | struct bio *split; | ||
2444 | |||
2445 | pd = q->queuedata; | ||
2446 | if (!pd) { | ||
2447 | pr_err("%s incorrect request queue\n", | ||
2448 | bdevname(bio->bi_bdev, b)); | ||
2449 | goto end_io; | ||
2450 | } | ||
2451 | |||
2452 | pkt_dbg(2, pd, "start = %6llx stop = %6llx\n", | ||
2453 | (unsigned long long)bio->bi_iter.bi_sector, | ||
2454 | (unsigned long long)bio_end_sector(bio)); | ||
2455 | |||
2456 | /* | ||
2457 | * Clone READ bios so we can have our own bi_end_io callback. | ||
2458 | */ | ||
2459 | if (bio_data_dir(bio) == READ) { | ||
2460 | pkt_make_request_read(pd, bio); | ||
2461 | return; | ||
2462 | } | ||
2463 | |||
2464 | if (!test_bit(PACKET_WRITABLE, &pd->flags)) { | ||
2465 | pkt_notice(pd, "WRITE for ro device (%llu)\n", | ||
2466 | (unsigned long long)bio->bi_iter.bi_sector); | ||
2467 | goto end_io; | ||
2468 | } | ||
2469 | |||
2470 | if (!bio->bi_iter.bi_size || (bio->bi_iter.bi_size % CD_FRAMESIZE)) { | ||
2471 | pkt_err(pd, "wrong bio size\n"); | ||
2472 | goto end_io; | ||
2473 | } | ||
2474 | |||
2475 | blk_queue_bounce(q, &bio); | ||
2476 | |||
2477 | do { | ||
2478 | sector_t zone = get_zone(bio->bi_iter.bi_sector, pd); | ||
2479 | sector_t last_zone = get_zone(bio_end_sector(bio) - 1, pd); | ||
2480 | |||
2481 | if (last_zone != zone) { | ||
2482 | BUG_ON(last_zone != zone + pd->settings.size); | ||
2483 | |||
2484 | split = bio_split(bio, last_zone - | ||
2485 | bio->bi_iter.bi_sector, | ||
2486 | GFP_NOIO, fs_bio_set); | ||
2487 | bio_chain(split, bio); | ||
2488 | } else { | ||
2489 | split = bio; | ||
2490 | } | ||
2491 | |||
2492 | pkt_make_request_write(q, split); | ||
2493 | } while (split != bio); | ||
2494 | |||
2483 | return; | 2495 | return; |
2484 | end_io: | 2496 | end_io: |
2485 | bio_io_error(bio); | 2497 | bio_io_error(bio); |