diff options
Diffstat (limited to 'fs/btrfs/volumes.c')
| -rw-r--r-- | fs/btrfs/volumes.c | 46 | 
1 files changed, 28 insertions, 18 deletions
| diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index bab0b84d8f80..d241130a32fd 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -415,7 +415,8 @@ loop_lock: | |||
| 415 | device->running_pending = 1; | 415 | device->running_pending = 1; | 
| 416 | 416 | ||
| 417 | spin_unlock(&device->io_lock); | 417 | spin_unlock(&device->io_lock); | 
| 418 | btrfs_requeue_work(&device->work); | 418 | btrfs_queue_work(fs_info->submit_workers, | 
| 419 | &device->work); | ||
| 419 | goto done; | 420 | goto done; | 
| 420 | } | 421 | } | 
| 421 | /* unplug every 64 requests just for good measure */ | 422 | /* unplug every 64 requests just for good measure */ | 
| @@ -5263,6 +5264,7 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, | |||
| 5263 | static void btrfs_end_bio(struct bio *bio, int err) | 5264 | static void btrfs_end_bio(struct bio *bio, int err) | 
| 5264 | { | 5265 | { | 
| 5265 | struct btrfs_bio *bbio = bio->bi_private; | 5266 | struct btrfs_bio *bbio = bio->bi_private; | 
| 5267 | struct btrfs_device *dev = bbio->stripes[0].dev; | ||
| 5266 | int is_orig_bio = 0; | 5268 | int is_orig_bio = 0; | 
| 5267 | 5269 | ||
| 5268 | if (err) { | 5270 | if (err) { | 
| @@ -5270,7 +5272,6 @@ static void btrfs_end_bio(struct bio *bio, int err) | |||
| 5270 | if (err == -EIO || err == -EREMOTEIO) { | 5272 | if (err == -EIO || err == -EREMOTEIO) { | 
| 5271 | unsigned int stripe_index = | 5273 | unsigned int stripe_index = | 
| 5272 | btrfs_io_bio(bio)->stripe_index; | 5274 | btrfs_io_bio(bio)->stripe_index; | 
| 5273 | struct btrfs_device *dev; | ||
| 5274 | 5275 | ||
| 5275 | BUG_ON(stripe_index >= bbio->num_stripes); | 5276 | BUG_ON(stripe_index >= bbio->num_stripes); | 
| 5276 | dev = bbio->stripes[stripe_index].dev; | 5277 | dev = bbio->stripes[stripe_index].dev; | 
| @@ -5292,6 +5293,8 @@ static void btrfs_end_bio(struct bio *bio, int err) | |||
| 5292 | if (bio == bbio->orig_bio) | 5293 | if (bio == bbio->orig_bio) | 
| 5293 | is_orig_bio = 1; | 5294 | is_orig_bio = 1; | 
| 5294 | 5295 | ||
| 5296 | btrfs_bio_counter_dec(bbio->fs_info); | ||
| 5297 | |||
| 5295 | if (atomic_dec_and_test(&bbio->stripes_pending)) { | 5298 | if (atomic_dec_and_test(&bbio->stripes_pending)) { | 
| 5296 | if (!is_orig_bio) { | 5299 | if (!is_orig_bio) { | 
| 5297 | bio_put(bio); | 5300 | bio_put(bio); | 
| @@ -5328,13 +5331,6 @@ static void btrfs_end_bio(struct bio *bio, int err) | |||
| 5328 | } | 5331 | } | 
| 5329 | } | 5332 | } | 
| 5330 | 5333 | ||
| 5331 | struct async_sched { | ||
| 5332 | struct bio *bio; | ||
| 5333 | int rw; | ||
| 5334 | struct btrfs_fs_info *info; | ||
| 5335 | struct btrfs_work work; | ||
| 5336 | }; | ||
| 5337 | |||
| 5338 | /* | 5334 | /* | 
| 5339 | * see run_scheduled_bios for a description of why bios are collected for | 5335 | * see run_scheduled_bios for a description of why bios are collected for | 
| 5340 | * async submit. | 5336 | * async submit. | 
| @@ -5391,8 +5387,8 @@ static noinline void btrfs_schedule_bio(struct btrfs_root *root, | |||
| 5391 | spin_unlock(&device->io_lock); | 5387 | spin_unlock(&device->io_lock); | 
| 5392 | 5388 | ||
| 5393 | if (should_queue) | 5389 | if (should_queue) | 
| 5394 | btrfs_queue_worker(&root->fs_info->submit_workers, | 5390 | btrfs_queue_work(root->fs_info->submit_workers, | 
| 5395 | &device->work); | 5391 | &device->work); | 
| 5396 | } | 5392 | } | 
| 5397 | 5393 | ||
| 5398 | static int bio_size_ok(struct block_device *bdev, struct bio *bio, | 5394 | static int bio_size_ok(struct block_device *bdev, struct bio *bio, | 
| @@ -5447,6 +5443,9 @@ static void submit_stripe_bio(struct btrfs_root *root, struct btrfs_bio *bbio, | |||
| 5447 | } | 5443 | } | 
| 5448 | #endif | 5444 | #endif | 
| 5449 | bio->bi_bdev = dev->bdev; | 5445 | bio->bi_bdev = dev->bdev; | 
| 5446 | |||
| 5447 | btrfs_bio_counter_inc_noblocked(root->fs_info); | ||
| 5448 | |||
| 5450 | if (async) | 5449 | if (async) | 
| 5451 | btrfs_schedule_bio(root, dev, rw, bio); | 5450 | btrfs_schedule_bio(root, dev, rw, bio); | 
| 5452 | else | 5451 | else | 
| @@ -5515,28 +5514,38 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, | |||
| 5515 | length = bio->bi_iter.bi_size; | 5514 | length = bio->bi_iter.bi_size; | 
| 5516 | map_length = length; | 5515 | map_length = length; | 
| 5517 | 5516 | ||
| 5517 | btrfs_bio_counter_inc_blocked(root->fs_info); | ||
| 5518 | ret = __btrfs_map_block(root->fs_info, rw, logical, &map_length, &bbio, | 5518 | ret = __btrfs_map_block(root->fs_info, rw, logical, &map_length, &bbio, | 
| 5519 | mirror_num, &raid_map); | 5519 | mirror_num, &raid_map); | 
| 5520 | if (ret) /* -ENOMEM */ | 5520 | if (ret) { | 
| 5521 | btrfs_bio_counter_dec(root->fs_info); | ||
| 5521 | return ret; | 5522 | return ret; | 
| 5523 | } | ||
| 5522 | 5524 | ||
| 5523 | total_devs = bbio->num_stripes; | 5525 | total_devs = bbio->num_stripes; | 
| 5524 | bbio->orig_bio = first_bio; | 5526 | bbio->orig_bio = first_bio; | 
| 5525 | bbio->private = first_bio->bi_private; | 5527 | bbio->private = first_bio->bi_private; | 
| 5526 | bbio->end_io = first_bio->bi_end_io; | 5528 | bbio->end_io = first_bio->bi_end_io; | 
| 5529 | bbio->fs_info = root->fs_info; | ||
| 5527 | atomic_set(&bbio->stripes_pending, bbio->num_stripes); | 5530 | atomic_set(&bbio->stripes_pending, bbio->num_stripes); | 
| 5528 | 5531 | ||
| 5529 | if (raid_map) { | 5532 | if (raid_map) { | 
| 5530 | /* In this case, map_length has been set to the length of | 5533 | /* In this case, map_length has been set to the length of | 
| 5531 | a single stripe; not the whole write */ | 5534 | a single stripe; not the whole write */ | 
| 5532 | if (rw & WRITE) { | 5535 | if (rw & WRITE) { | 
| 5533 | return raid56_parity_write(root, bio, bbio, | 5536 | ret = raid56_parity_write(root, bio, bbio, | 
| 5534 | raid_map, map_length); | 5537 | raid_map, map_length); | 
| 5535 | } else { | 5538 | } else { | 
| 5536 | return raid56_parity_recover(root, bio, bbio, | 5539 | ret = raid56_parity_recover(root, bio, bbio, | 
| 5537 | raid_map, map_length, | 5540 | raid_map, map_length, | 
| 5538 | mirror_num); | 5541 | mirror_num); | 
| 5539 | } | 5542 | } | 
| 5543 | /* | ||
| 5544 | * FIXME, replace dosen't support raid56 yet, please fix | ||
| 5545 | * it in the future. | ||
| 5546 | */ | ||
| 5547 | btrfs_bio_counter_dec(root->fs_info); | ||
| 5548 | return ret; | ||
| 5540 | } | 5549 | } | 
| 5541 | 5550 | ||
| 5542 | if (map_length < length) { | 5551 | if (map_length < length) { | 
| @@ -5578,6 +5587,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio, | |||
| 5578 | async_submit); | 5587 | async_submit); | 
| 5579 | dev_nr++; | 5588 | dev_nr++; | 
| 5580 | } | 5589 | } | 
| 5590 | btrfs_bio_counter_dec(root->fs_info); | ||
| 5581 | return 0; | 5591 | return 0; | 
| 5582 | } | 5592 | } | 
| 5583 | 5593 | ||
| @@ -5666,7 +5676,7 @@ struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info, | |||
| 5666 | else | 5676 | else | 
| 5667 | generate_random_uuid(dev->uuid); | 5677 | generate_random_uuid(dev->uuid); | 
| 5668 | 5678 | ||
| 5669 | dev->work.func = pending_bios_fn; | 5679 | btrfs_init_work(&dev->work, pending_bios_fn, NULL, NULL); | 
| 5670 | 5680 | ||
| 5671 | return dev; | 5681 | return dev; | 
| 5672 | } | 5682 | } | 
