diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 111 |
1 files changed, 70 insertions, 41 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 7ae51decf6d3..2936ca49b3b4 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include "free-space-cache.h" | 44 | #include "free-space-cache.h" |
45 | #include "inode-map.h" | 45 | #include "inode-map.h" |
46 | #include "check-integrity.h" | 46 | #include "check-integrity.h" |
47 | #include "rcu-string.h" | ||
47 | 48 | ||
48 | static struct extent_io_ops btree_extent_io_ops; | 49 | static struct extent_io_ops btree_extent_io_ops; |
49 | static void end_workqueue_fn(struct btrfs_work *work); | 50 | static void end_workqueue_fn(struct btrfs_work *work); |
@@ -2118,7 +2119,7 @@ int open_ctree(struct super_block *sb, | |||
2118 | 2119 | ||
2119 | features = btrfs_super_incompat_flags(disk_super); | 2120 | features = btrfs_super_incompat_flags(disk_super); |
2120 | features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF; | 2121 | features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF; |
2121 | if (tree_root->fs_info->compress_type & BTRFS_COMPRESS_LZO) | 2122 | if (tree_root->fs_info->compress_type == BTRFS_COMPRESS_LZO) |
2122 | features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO; | 2123 | features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO; |
2123 | 2124 | ||
2124 | /* | 2125 | /* |
@@ -2353,12 +2354,17 @@ retry_root_backup: | |||
2353 | BTRFS_CSUM_TREE_OBJECTID, csum_root); | 2354 | BTRFS_CSUM_TREE_OBJECTID, csum_root); |
2354 | if (ret) | 2355 | if (ret) |
2355 | goto recovery_tree_root; | 2356 | goto recovery_tree_root; |
2356 | |||
2357 | csum_root->track_dirty = 1; | 2357 | csum_root->track_dirty = 1; |
2358 | 2358 | ||
2359 | fs_info->generation = generation; | 2359 | fs_info->generation = generation; |
2360 | fs_info->last_trans_committed = generation; | 2360 | fs_info->last_trans_committed = generation; |
2361 | 2361 | ||
2362 | ret = btrfs_recover_balance(fs_info); | ||
2363 | if (ret) { | ||
2364 | printk(KERN_WARNING "btrfs: failed to recover balance\n"); | ||
2365 | goto fail_block_groups; | ||
2366 | } | ||
2367 | |||
2362 | ret = btrfs_init_dev_stats(fs_info); | 2368 | ret = btrfs_init_dev_stats(fs_info); |
2363 | if (ret) { | 2369 | if (ret) { |
2364 | printk(KERN_ERR "btrfs: failed to init dev_stats: %d\n", | 2370 | printk(KERN_ERR "btrfs: failed to init dev_stats: %d\n", |
@@ -2484,20 +2490,23 @@ retry_root_backup: | |||
2484 | goto fail_trans_kthread; | 2490 | goto fail_trans_kthread; |
2485 | } | 2491 | } |
2486 | 2492 | ||
2487 | if (!(sb->s_flags & MS_RDONLY)) { | 2493 | if (sb->s_flags & MS_RDONLY) |
2488 | down_read(&fs_info->cleanup_work_sem); | 2494 | return 0; |
2489 | err = btrfs_orphan_cleanup(fs_info->fs_root); | ||
2490 | if (!err) | ||
2491 | err = btrfs_orphan_cleanup(fs_info->tree_root); | ||
2492 | up_read(&fs_info->cleanup_work_sem); | ||
2493 | 2495 | ||
2494 | if (!err) | 2496 | down_read(&fs_info->cleanup_work_sem); |
2495 | err = btrfs_recover_balance(fs_info->tree_root); | 2497 | if ((ret = btrfs_orphan_cleanup(fs_info->fs_root)) || |
2498 | (ret = btrfs_orphan_cleanup(fs_info->tree_root))) { | ||
2499 | up_read(&fs_info->cleanup_work_sem); | ||
2500 | close_ctree(tree_root); | ||
2501 | return ret; | ||
2502 | } | ||
2503 | up_read(&fs_info->cleanup_work_sem); | ||
2496 | 2504 | ||
2497 | if (err) { | 2505 | ret = btrfs_resume_balance_async(fs_info); |
2498 | close_ctree(tree_root); | 2506 | if (ret) { |
2499 | return err; | 2507 | printk(KERN_WARNING "btrfs: failed to resume balance\n"); |
2500 | } | 2508 | close_ctree(tree_root); |
2509 | return ret; | ||
2501 | } | 2510 | } |
2502 | 2511 | ||
2503 | return 0; | 2512 | return 0; |
@@ -2575,8 +2584,9 @@ static void btrfs_end_buffer_write_sync(struct buffer_head *bh, int uptodate) | |||
2575 | struct btrfs_device *device = (struct btrfs_device *) | 2584 | struct btrfs_device *device = (struct btrfs_device *) |
2576 | bh->b_private; | 2585 | bh->b_private; |
2577 | 2586 | ||
2578 | printk_ratelimited(KERN_WARNING "lost page write due to " | 2587 | printk_ratelimited_in_rcu(KERN_WARNING "lost page write due to " |
2579 | "I/O error on %s\n", device->name); | 2588 | "I/O error on %s\n", |
2589 | rcu_str_deref(device->name)); | ||
2580 | /* note, we dont' set_buffer_write_io_error because we have | 2590 | /* note, we dont' set_buffer_write_io_error because we have |
2581 | * our own ways of dealing with the IO errors | 2591 | * our own ways of dealing with the IO errors |
2582 | */ | 2592 | */ |
@@ -2749,8 +2759,8 @@ static int write_dev_flush(struct btrfs_device *device, int wait) | |||
2749 | wait_for_completion(&device->flush_wait); | 2759 | wait_for_completion(&device->flush_wait); |
2750 | 2760 | ||
2751 | if (bio_flagged(bio, BIO_EOPNOTSUPP)) { | 2761 | if (bio_flagged(bio, BIO_EOPNOTSUPP)) { |
2752 | printk("btrfs: disabling barriers on dev %s\n", | 2762 | printk_in_rcu("btrfs: disabling barriers on dev %s\n", |
2753 | device->name); | 2763 | rcu_str_deref(device->name)); |
2754 | device->nobarriers = 1; | 2764 | device->nobarriers = 1; |
2755 | } | 2765 | } |
2756 | if (!bio_flagged(bio, BIO_UPTODATE)) { | 2766 | if (!bio_flagged(bio, BIO_UPTODATE)) { |
@@ -3400,7 +3410,6 @@ int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, | |||
3400 | 3410 | ||
3401 | delayed_refs = &trans->delayed_refs; | 3411 | delayed_refs = &trans->delayed_refs; |
3402 | 3412 | ||
3403 | again: | ||
3404 | spin_lock(&delayed_refs->lock); | 3413 | spin_lock(&delayed_refs->lock); |
3405 | if (delayed_refs->num_entries == 0) { | 3414 | if (delayed_refs->num_entries == 0) { |
3406 | spin_unlock(&delayed_refs->lock); | 3415 | spin_unlock(&delayed_refs->lock); |
@@ -3408,31 +3417,37 @@ again: | |||
3408 | return ret; | 3417 | return ret; |
3409 | } | 3418 | } |
3410 | 3419 | ||
3411 | node = rb_first(&delayed_refs->root); | 3420 | while ((node = rb_first(&delayed_refs->root)) != NULL) { |
3412 | while (node) { | ||
3413 | ref = rb_entry(node, struct btrfs_delayed_ref_node, rb_node); | 3421 | ref = rb_entry(node, struct btrfs_delayed_ref_node, rb_node); |
3414 | node = rb_next(node); | ||
3415 | |||
3416 | ref->in_tree = 0; | ||
3417 | rb_erase(&ref->rb_node, &delayed_refs->root); | ||
3418 | delayed_refs->num_entries--; | ||
3419 | 3422 | ||
3420 | atomic_set(&ref->refs, 1); | 3423 | atomic_set(&ref->refs, 1); |
3421 | if (btrfs_delayed_ref_is_head(ref)) { | 3424 | if (btrfs_delayed_ref_is_head(ref)) { |
3422 | struct btrfs_delayed_ref_head *head; | 3425 | struct btrfs_delayed_ref_head *head; |
3423 | 3426 | ||
3424 | head = btrfs_delayed_node_to_head(ref); | 3427 | head = btrfs_delayed_node_to_head(ref); |
3425 | spin_unlock(&delayed_refs->lock); | 3428 | if (!mutex_trylock(&head->mutex)) { |
3426 | mutex_lock(&head->mutex); | 3429 | atomic_inc(&ref->refs); |
3430 | spin_unlock(&delayed_refs->lock); | ||
3431 | |||
3432 | /* Need to wait for the delayed ref to run */ | ||
3433 | mutex_lock(&head->mutex); | ||
3434 | mutex_unlock(&head->mutex); | ||
3435 | btrfs_put_delayed_ref(ref); | ||
3436 | |||
3437 | spin_lock(&delayed_refs->lock); | ||
3438 | continue; | ||
3439 | } | ||
3440 | |||
3427 | kfree(head->extent_op); | 3441 | kfree(head->extent_op); |
3428 | delayed_refs->num_heads--; | 3442 | delayed_refs->num_heads--; |
3429 | if (list_empty(&head->cluster)) | 3443 | if (list_empty(&head->cluster)) |
3430 | delayed_refs->num_heads_ready--; | 3444 | delayed_refs->num_heads_ready--; |
3431 | list_del_init(&head->cluster); | 3445 | list_del_init(&head->cluster); |
3432 | mutex_unlock(&head->mutex); | ||
3433 | btrfs_put_delayed_ref(ref); | ||
3434 | goto again; | ||
3435 | } | 3446 | } |
3447 | ref->in_tree = 0; | ||
3448 | rb_erase(&ref->rb_node, &delayed_refs->root); | ||
3449 | delayed_refs->num_entries--; | ||
3450 | |||
3436 | spin_unlock(&delayed_refs->lock); | 3451 | spin_unlock(&delayed_refs->lock); |
3437 | btrfs_put_delayed_ref(ref); | 3452 | btrfs_put_delayed_ref(ref); |
3438 | 3453 | ||
@@ -3520,11 +3535,9 @@ static int btrfs_destroy_marked_extents(struct btrfs_root *root, | |||
3520 | &(&BTRFS_I(page->mapping->host)->io_tree)->buffer, | 3535 | &(&BTRFS_I(page->mapping->host)->io_tree)->buffer, |
3521 | offset >> PAGE_CACHE_SHIFT); | 3536 | offset >> PAGE_CACHE_SHIFT); |
3522 | spin_unlock(&dirty_pages->buffer_lock); | 3537 | spin_unlock(&dirty_pages->buffer_lock); |
3523 | if (eb) { | 3538 | if (eb) |
3524 | ret = test_and_clear_bit(EXTENT_BUFFER_DIRTY, | 3539 | ret = test_and_clear_bit(EXTENT_BUFFER_DIRTY, |
3525 | &eb->bflags); | 3540 | &eb->bflags); |
3526 | atomic_set(&eb->refs, 1); | ||
3527 | } | ||
3528 | if (PageWriteback(page)) | 3541 | if (PageWriteback(page)) |
3529 | end_page_writeback(page); | 3542 | end_page_writeback(page); |
3530 | 3543 | ||
@@ -3538,8 +3551,8 @@ static int btrfs_destroy_marked_extents(struct btrfs_root *root, | |||
3538 | spin_unlock_irq(&page->mapping->tree_lock); | 3551 | spin_unlock_irq(&page->mapping->tree_lock); |
3539 | } | 3552 | } |
3540 | 3553 | ||
3541 | page->mapping->a_ops->invalidatepage(page, 0); | ||
3542 | unlock_page(page); | 3554 | unlock_page(page); |
3555 | page_cache_release(page); | ||
3543 | } | 3556 | } |
3544 | } | 3557 | } |
3545 | 3558 | ||
@@ -3553,8 +3566,10 @@ static int btrfs_destroy_pinned_extent(struct btrfs_root *root, | |||
3553 | u64 start; | 3566 | u64 start; |
3554 | u64 end; | 3567 | u64 end; |
3555 | int ret; | 3568 | int ret; |
3569 | bool loop = true; | ||
3556 | 3570 | ||
3557 | unpin = pinned_extents; | 3571 | unpin = pinned_extents; |
3572 | again: | ||
3558 | while (1) { | 3573 | while (1) { |
3559 | ret = find_first_extent_bit(unpin, 0, &start, &end, | 3574 | ret = find_first_extent_bit(unpin, 0, &start, &end, |
3560 | EXTENT_DIRTY); | 3575 | EXTENT_DIRTY); |
@@ -3572,6 +3587,15 @@ static int btrfs_destroy_pinned_extent(struct btrfs_root *root, | |||
3572 | cond_resched(); | 3587 | cond_resched(); |
3573 | } | 3588 | } |
3574 | 3589 | ||
3590 | if (loop) { | ||
3591 | if (unpin == &root->fs_info->freed_extents[0]) | ||
3592 | unpin = &root->fs_info->freed_extents[1]; | ||
3593 | else | ||
3594 | unpin = &root->fs_info->freed_extents[0]; | ||
3595 | loop = false; | ||
3596 | goto again; | ||
3597 | } | ||
3598 | |||
3575 | return 0; | 3599 | return 0; |
3576 | } | 3600 | } |
3577 | 3601 | ||
@@ -3585,21 +3609,23 @@ void btrfs_cleanup_one_transaction(struct btrfs_transaction *cur_trans, | |||
3585 | /* FIXME: cleanup wait for commit */ | 3609 | /* FIXME: cleanup wait for commit */ |
3586 | cur_trans->in_commit = 1; | 3610 | cur_trans->in_commit = 1; |
3587 | cur_trans->blocked = 1; | 3611 | cur_trans->blocked = 1; |
3588 | if (waitqueue_active(&root->fs_info->transaction_blocked_wait)) | 3612 | wake_up(&root->fs_info->transaction_blocked_wait); |
3589 | wake_up(&root->fs_info->transaction_blocked_wait); | ||
3590 | 3613 | ||
3591 | cur_trans->blocked = 0; | 3614 | cur_trans->blocked = 0; |
3592 | if (waitqueue_active(&root->fs_info->transaction_wait)) | 3615 | wake_up(&root->fs_info->transaction_wait); |
3593 | wake_up(&root->fs_info->transaction_wait); | ||
3594 | 3616 | ||
3595 | cur_trans->commit_done = 1; | 3617 | cur_trans->commit_done = 1; |
3596 | if (waitqueue_active(&cur_trans->commit_wait)) | 3618 | wake_up(&cur_trans->commit_wait); |
3597 | wake_up(&cur_trans->commit_wait); | 3619 | |
3620 | btrfs_destroy_delayed_inodes(root); | ||
3621 | btrfs_assert_delayed_root_empty(root); | ||
3598 | 3622 | ||
3599 | btrfs_destroy_pending_snapshots(cur_trans); | 3623 | btrfs_destroy_pending_snapshots(cur_trans); |
3600 | 3624 | ||
3601 | btrfs_destroy_marked_extents(root, &cur_trans->dirty_pages, | 3625 | btrfs_destroy_marked_extents(root, &cur_trans->dirty_pages, |
3602 | EXTENT_DIRTY); | 3626 | EXTENT_DIRTY); |
3627 | btrfs_destroy_pinned_extent(root, | ||
3628 | root->fs_info->pinned_extents); | ||
3603 | 3629 | ||
3604 | /* | 3630 | /* |
3605 | memset(cur_trans, 0, sizeof(*cur_trans)); | 3631 | memset(cur_trans, 0, sizeof(*cur_trans)); |
@@ -3648,6 +3674,9 @@ int btrfs_cleanup_transaction(struct btrfs_root *root) | |||
3648 | if (waitqueue_active(&t->commit_wait)) | 3674 | if (waitqueue_active(&t->commit_wait)) |
3649 | wake_up(&t->commit_wait); | 3675 | wake_up(&t->commit_wait); |
3650 | 3676 | ||
3677 | btrfs_destroy_delayed_inodes(root); | ||
3678 | btrfs_assert_delayed_root_empty(root); | ||
3679 | |||
3651 | btrfs_destroy_pending_snapshots(t); | 3680 | btrfs_destroy_pending_snapshots(t); |
3652 | 3681 | ||
3653 | btrfs_destroy_delalloc_inodes(root); | 3682 | btrfs_destroy_delalloc_inodes(root); |