aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c71
1 files changed, 41 insertions, 30 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 5699bbc23feb..4b02591b0301 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -50,6 +50,7 @@
50#include "raid56.h" 50#include "raid56.h"
51#include "sysfs.h" 51#include "sysfs.h"
52#include "qgroup.h" 52#include "qgroup.h"
53#include "compression.h"
53 54
54#ifdef CONFIG_X86 55#ifdef CONFIG_X86
55#include <asm/cpufeature.h> 56#include <asm/cpufeature.h>
@@ -110,8 +111,7 @@ int __init btrfs_end_io_wq_init(void)
110 111
111void btrfs_end_io_wq_exit(void) 112void btrfs_end_io_wq_exit(void)
112{ 113{
113 if (btrfs_end_io_wq_cache) 114 kmem_cache_destroy(btrfs_end_io_wq_cache);
114 kmem_cache_destroy(btrfs_end_io_wq_cache);
115} 115}
116 116
117/* 117/*
@@ -612,6 +612,7 @@ static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
612 int found_level; 612 int found_level;
613 struct extent_buffer *eb; 613 struct extent_buffer *eb;
614 struct btrfs_root *root = BTRFS_I(page->mapping->host)->root; 614 struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;
615 struct btrfs_fs_info *fs_info = root->fs_info;
615 int ret = 0; 616 int ret = 0;
616 int reads_done; 617 int reads_done;
617 618
@@ -637,21 +638,21 @@ static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
637 638
638 found_start = btrfs_header_bytenr(eb); 639 found_start = btrfs_header_bytenr(eb);
639 if (found_start != eb->start) { 640 if (found_start != eb->start) {
640 btrfs_err_rl(eb->fs_info, "bad tree block start %llu %llu", 641 btrfs_err_rl(fs_info, "bad tree block start %llu %llu",
641 found_start, eb->start); 642 found_start, eb->start);
642 ret = -EIO; 643 ret = -EIO;
643 goto err; 644 goto err;
644 } 645 }
645 if (check_tree_block_fsid(root->fs_info, eb)) { 646 if (check_tree_block_fsid(fs_info, eb)) {
646 btrfs_err_rl(eb->fs_info, "bad fsid on block %llu", 647 btrfs_err_rl(fs_info, "bad fsid on block %llu",
647 eb->start); 648 eb->start);
648 ret = -EIO; 649 ret = -EIO;
649 goto err; 650 goto err;
650 } 651 }
651 found_level = btrfs_header_level(eb); 652 found_level = btrfs_header_level(eb);
652 if (found_level >= BTRFS_MAX_LEVEL) { 653 if (found_level >= BTRFS_MAX_LEVEL) {
653 btrfs_err(root->fs_info, "bad tree block level %d", 654 btrfs_err(fs_info, "bad tree block level %d",
654 (int)btrfs_header_level(eb)); 655 (int)btrfs_header_level(eb));
655 ret = -EIO; 656 ret = -EIO;
656 goto err; 657 goto err;
657 } 658 }
@@ -659,7 +660,7 @@ static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
659 btrfs_set_buffer_lockdep_class(btrfs_header_owner(eb), 660 btrfs_set_buffer_lockdep_class(btrfs_header_owner(eb),
660 eb, found_level); 661 eb, found_level);
661 662
662 ret = csum_tree_block(root->fs_info, eb, 1); 663 ret = csum_tree_block(fs_info, eb, 1);
663 if (ret) { 664 if (ret) {
664 ret = -EIO; 665 ret = -EIO;
665 goto err; 666 goto err;
@@ -680,7 +681,7 @@ static int btree_readpage_end_io_hook(struct btrfs_io_bio *io_bio,
680err: 681err:
681 if (reads_done && 682 if (reads_done &&
682 test_and_clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) 683 test_and_clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags))
683 btree_readahead_hook(root, eb, eb->start, ret); 684 btree_readahead_hook(fs_info, eb, eb->start, ret);
684 685
685 if (ret) { 686 if (ret) {
686 /* 687 /*
@@ -699,14 +700,13 @@ out:
699static int btree_io_failed_hook(struct page *page, int failed_mirror) 700static int btree_io_failed_hook(struct page *page, int failed_mirror)
700{ 701{
701 struct extent_buffer *eb; 702 struct extent_buffer *eb;
702 struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;
703 703
704 eb = (struct extent_buffer *)page->private; 704 eb = (struct extent_buffer *)page->private;
705 set_bit(EXTENT_BUFFER_READ_ERR, &eb->bflags); 705 set_bit(EXTENT_BUFFER_READ_ERR, &eb->bflags);
706 eb->read_mirror = failed_mirror; 706 eb->read_mirror = failed_mirror;
707 atomic_dec(&eb->io_pages); 707 atomic_dec(&eb->io_pages);
708 if (test_and_clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags)) 708 if (test_and_clear_bit(EXTENT_BUFFER_READAHEAD, &eb->bflags))
709 btree_readahead_hook(root, eb, eb->start, -EIO); 709 btree_readahead_hook(eb->fs_info, eb, eb->start, -EIO);
710 return -EIO; /* we fixed nothing */ 710 return -EIO; /* we fixed nothing */
711} 711}
712 712
@@ -816,7 +816,7 @@ static void run_one_async_done(struct btrfs_work *work)
816 waitqueue_active(&fs_info->async_submit_wait)) 816 waitqueue_active(&fs_info->async_submit_wait))
817 wake_up(&fs_info->async_submit_wait); 817 wake_up(&fs_info->async_submit_wait);
818 818
819 /* If an error occured we just want to clean up the bio and move on */ 819 /* If an error occurred we just want to clean up the bio and move on */
820 if (async->error) { 820 if (async->error) {
821 async->bio->bi_error = async->error; 821 async->bio->bi_error = async->error;
822 bio_endio(async->bio); 822 bio_endio(async->bio);
@@ -1296,9 +1296,10 @@ static void __setup_root(u32 nodesize, u32 sectorsize, u32 stripesize,
1296 spin_lock_init(&root->root_item_lock); 1296 spin_lock_init(&root->root_item_lock);
1297} 1297}
1298 1298
1299static struct btrfs_root *btrfs_alloc_root(struct btrfs_fs_info *fs_info) 1299static struct btrfs_root *btrfs_alloc_root(struct btrfs_fs_info *fs_info,
1300 gfp_t flags)
1300{ 1301{
1301 struct btrfs_root *root = kzalloc(sizeof(*root), GFP_NOFS); 1302 struct btrfs_root *root = kzalloc(sizeof(*root), flags);
1302 if (root) 1303 if (root)
1303 root->fs_info = fs_info; 1304 root->fs_info = fs_info;
1304 return root; 1305 return root;
@@ -1310,7 +1311,7 @@ struct btrfs_root *btrfs_alloc_dummy_root(void)
1310{ 1311{
1311 struct btrfs_root *root; 1312 struct btrfs_root *root;
1312 1313
1313 root = btrfs_alloc_root(NULL); 1314 root = btrfs_alloc_root(NULL, GFP_KERNEL);
1314 if (!root) 1315 if (!root)
1315 return ERR_PTR(-ENOMEM); 1316 return ERR_PTR(-ENOMEM);
1316 __setup_root(4096, 4096, 4096, root, NULL, 1); 1317 __setup_root(4096, 4096, 4096, root, NULL, 1);
@@ -1332,7 +1333,7 @@ struct btrfs_root *btrfs_create_tree(struct btrfs_trans_handle *trans,
1332 int ret = 0; 1333 int ret = 0;
1333 uuid_le uuid; 1334 uuid_le uuid;
1334 1335
1335 root = btrfs_alloc_root(fs_info); 1336 root = btrfs_alloc_root(fs_info, GFP_KERNEL);
1336 if (!root) 1337 if (!root)
1337 return ERR_PTR(-ENOMEM); 1338 return ERR_PTR(-ENOMEM);
1338 1339
@@ -1408,7 +1409,7 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans,
1408 struct btrfs_root *tree_root = fs_info->tree_root; 1409 struct btrfs_root *tree_root = fs_info->tree_root;
1409 struct extent_buffer *leaf; 1410 struct extent_buffer *leaf;
1410 1411
1411 root = btrfs_alloc_root(fs_info); 1412 root = btrfs_alloc_root(fs_info, GFP_NOFS);
1412 if (!root) 1413 if (!root)
1413 return ERR_PTR(-ENOMEM); 1414 return ERR_PTR(-ENOMEM);
1414 1415
@@ -1506,7 +1507,7 @@ static struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
1506 if (!path) 1507 if (!path)
1507 return ERR_PTR(-ENOMEM); 1508 return ERR_PTR(-ENOMEM);
1508 1509
1509 root = btrfs_alloc_root(fs_info); 1510 root = btrfs_alloc_root(fs_info, GFP_NOFS);
1510 if (!root) { 1511 if (!root) {
1511 ret = -ENOMEM; 1512 ret = -ENOMEM;
1512 goto alloc_fail; 1513 goto alloc_fail;
@@ -2272,9 +2273,11 @@ static void btrfs_init_dev_replace_locks(struct btrfs_fs_info *fs_info)
2272 fs_info->dev_replace.lock_owner = 0; 2273 fs_info->dev_replace.lock_owner = 0;
2273 atomic_set(&fs_info->dev_replace.nesting_level, 0); 2274 atomic_set(&fs_info->dev_replace.nesting_level, 0);
2274 mutex_init(&fs_info->dev_replace.lock_finishing_cancel_unmount); 2275 mutex_init(&fs_info->dev_replace.lock_finishing_cancel_unmount);
2275 mutex_init(&fs_info->dev_replace.lock_management_lock); 2276 rwlock_init(&fs_info->dev_replace.lock);
2276 mutex_init(&fs_info->dev_replace.lock); 2277 atomic_set(&fs_info->dev_replace.read_locks, 0);
2278 atomic_set(&fs_info->dev_replace.blocking_readers, 0);
2277 init_waitqueue_head(&fs_info->replace_wait); 2279 init_waitqueue_head(&fs_info->replace_wait);
2280 init_waitqueue_head(&fs_info->dev_replace.read_lock_wq);
2278} 2281}
2279 2282
2280static void btrfs_init_qgroup(struct btrfs_fs_info *fs_info) 2283static void btrfs_init_qgroup(struct btrfs_fs_info *fs_info)
@@ -2385,7 +2388,7 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
2385 return -EIO; 2388 return -EIO;
2386 } 2389 }
2387 2390
2388 log_tree_root = btrfs_alloc_root(fs_info); 2391 log_tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
2389 if (!log_tree_root) 2392 if (!log_tree_root)
2390 return -ENOMEM; 2393 return -ENOMEM;
2391 2394
@@ -2510,8 +2513,8 @@ int open_ctree(struct super_block *sb,
2510 int backup_index = 0; 2513 int backup_index = 0;
2511 int max_active; 2514 int max_active;
2512 2515
2513 tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info); 2516 tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
2514 chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info); 2517 chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
2515 if (!tree_root || !chunk_root) { 2518 if (!tree_root || !chunk_root) {
2516 err = -ENOMEM; 2519 err = -ENOMEM;
2517 goto fail; 2520 goto fail;
@@ -2603,6 +2606,7 @@ int open_ctree(struct super_block *sb,
2603 atomic_set(&fs_info->nr_async_bios, 0); 2606 atomic_set(&fs_info->nr_async_bios, 0);
2604 atomic_set(&fs_info->defrag_running, 0); 2607 atomic_set(&fs_info->defrag_running, 0);
2605 atomic_set(&fs_info->qgroup_op_seq, 0); 2608 atomic_set(&fs_info->qgroup_op_seq, 0);
2609 atomic_set(&fs_info->reada_works_cnt, 0);
2606 atomic64_set(&fs_info->tree_mod_seq, 0); 2610 atomic64_set(&fs_info->tree_mod_seq, 0);
2607 fs_info->sb = sb; 2611 fs_info->sb = sb;
2608 fs_info->max_inline = BTRFS_DEFAULT_MAX_INLINE; 2612 fs_info->max_inline = BTRFS_DEFAULT_MAX_INLINE;
@@ -2622,7 +2626,7 @@ int open_ctree(struct super_block *sb,
2622 INIT_LIST_HEAD(&fs_info->ordered_roots); 2626 INIT_LIST_HEAD(&fs_info->ordered_roots);
2623 spin_lock_init(&fs_info->ordered_root_lock); 2627 spin_lock_init(&fs_info->ordered_root_lock);
2624 fs_info->delayed_root = kmalloc(sizeof(struct btrfs_delayed_root), 2628 fs_info->delayed_root = kmalloc(sizeof(struct btrfs_delayed_root),
2625 GFP_NOFS); 2629 GFP_KERNEL);
2626 if (!fs_info->delayed_root) { 2630 if (!fs_info->delayed_root) {
2627 err = -ENOMEM; 2631 err = -ENOMEM;
2628 goto fail_iput; 2632 goto fail_iput;
@@ -2750,7 +2754,7 @@ int open_ctree(struct super_block *sb,
2750 */ 2754 */
2751 fs_info->compress_type = BTRFS_COMPRESS_ZLIB; 2755 fs_info->compress_type = BTRFS_COMPRESS_ZLIB;
2752 2756
2753 ret = btrfs_parse_options(tree_root, options); 2757 ret = btrfs_parse_options(tree_root, options, sb->s_flags);
2754 if (ret) { 2758 if (ret) {
2755 err = ret; 2759 err = ret;
2756 goto fail_alloc; 2760 goto fail_alloc;
@@ -3029,8 +3033,9 @@ retry_root_backup:
3029 if (ret) 3033 if (ret)
3030 goto fail_trans_kthread; 3034 goto fail_trans_kthread;
3031 3035
3032 /* do not make disk changes in broken FS */ 3036 /* do not make disk changes in broken FS or nologreplay is given */
3033 if (btrfs_super_log_root(disk_super) != 0) { 3037 if (btrfs_super_log_root(disk_super) != 0 &&
3038 !btrfs_test_opt(tree_root, NOLOGREPLAY)) {
3034 ret = btrfs_replay_log(fs_info, fs_devices); 3039 ret = btrfs_replay_log(fs_info, fs_devices);
3035 if (ret) { 3040 if (ret) {
3036 err = ret; 3041 err = ret;
@@ -3146,6 +3151,12 @@ retry_root_backup:
3146 3151
3147 fs_info->open = 1; 3152 fs_info->open = 1;
3148 3153
3154 /*
3155 * backuproot only affect mount behavior, and if open_ctree succeeded,
3156 * no need to keep the flag
3157 */
3158 btrfs_clear_opt(fs_info->mount_opt, USEBACKUPROOT);
3159
3149 return 0; 3160 return 0;
3150 3161
3151fail_qgroup: 3162fail_qgroup:
@@ -3200,7 +3211,7 @@ fail:
3200 return err; 3211 return err;
3201 3212
3202recovery_tree_root: 3213recovery_tree_root:
3203 if (!btrfs_test_opt(tree_root, RECOVERY)) 3214 if (!btrfs_test_opt(tree_root, USEBACKUPROOT))
3204 goto fail_tree_roots; 3215 goto fail_tree_roots;
3205 3216
3206 free_root_pointers(fs_info, 0); 3217 free_root_pointers(fs_info, 0);