diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-21 21:12:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-21 21:12:42 -0400 |
commit | 968f3e374faf41e5e6049399eb7302777a09a1e8 (patch) | |
tree | 613c5aa9a005cfbe3fada77fcb0ab24deda126d9 /fs/btrfs/disk-io.c | |
parent | e531cdf50a8a0fb7a4d51c06e52097bd01e9bf7c (diff) | |
parent | 389f239c53420802ad5085e51e88c37e2df5e003 (diff) |
Merge branch 'for-linus-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs updates from Chris Mason:
"We have a good sized cleanup of our internal read ahead code, and the
first series of commits from Chandan to enable PAGE_SIZE > sectorsize
Otherwise, it's a normal series of cleanups and fixes, with many
thanks to Dave Sterba for doing most of the patch wrangling this time"
* 'for-linus-4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (82 commits)
btrfs: make sure we stay inside the bvec during __btrfs_lookup_bio_sums
btrfs: Fix misspellings in comments.
btrfs: Print Warning only if ENOSPC_DEBUG is enabled
btrfs: scrub: silence an uninitialized variable warning
btrfs: move btrfs_compression_type to compression.h
btrfs: rename btrfs_print_info to btrfs_print_mod_info
Btrfs: Show a warning message if one of objectid reaches its highest value
Documentation: btrfs: remove usage specific information
btrfs: use kbasename in btrfsic_mount
Btrfs: do not collect ordered extents when logging that inode exists
Btrfs: fix race when checking if we can skip fsync'ing an inode
Btrfs: fix listxattrs not listing all xattrs packed in the same item
Btrfs: fix deadlock between direct IO reads and buffered writes
Btrfs: fix extent_same allowing destination offset beyond i_size
Btrfs: fix file loss on log replay after renaming a file and fsync
Btrfs: fix unreplayable log after snapshot delete + parent dir fsync
Btrfs: fix lockdep deadlock warning due to dev_replace
btrfs: drop unused argument in btrfs_ioctl_get_supported_features
btrfs: add GET_SUPPORTED_FEATURES to the control device ioctls
btrfs: change max_inline default to 2048
...
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 71 |
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 | ||
111 | void btrfs_end_io_wq_exit(void) | 112 | void 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, | |||
680 | err: | 681 | err: |
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: | |||
699 | static int btree_io_failed_hook(struct page *page, int failed_mirror) | 700 | static 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 | ||
1299 | static struct btrfs_root *btrfs_alloc_root(struct btrfs_fs_info *fs_info) | 1299 | static 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 | ||
2280 | static void btrfs_init_qgroup(struct btrfs_fs_info *fs_info) | 2283 | static 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 | ||
3151 | fail_qgroup: | 3162 | fail_qgroup: |
@@ -3200,7 +3211,7 @@ fail: | |||
3200 | return err; | 3211 | return err; |
3201 | 3212 | ||
3202 | recovery_tree_root: | 3213 | recovery_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); |