diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 69 |
1 files changed, 40 insertions, 29 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 2ef9a4b72d06..3f43bfea3684 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1149,12 +1149,12 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, | |||
1149 | 1149 | ||
1150 | buf = btrfs_find_create_tree_block(root, bytenr); | 1150 | buf = btrfs_find_create_tree_block(root, bytenr); |
1151 | if (!buf) | 1151 | if (!buf) |
1152 | return NULL; | 1152 | return ERR_PTR(-ENOMEM); |
1153 | 1153 | ||
1154 | ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); | 1154 | ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); |
1155 | if (ret) { | 1155 | if (ret) { |
1156 | free_extent_buffer(buf); | 1156 | free_extent_buffer(buf); |
1157 | return NULL; | 1157 | return ERR_PTR(ret); |
1158 | } | 1158 | } |
1159 | return buf; | 1159 | return buf; |
1160 | 1160 | ||
@@ -1509,20 +1509,19 @@ static struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root, | |||
1509 | generation = btrfs_root_generation(&root->root_item); | 1509 | generation = btrfs_root_generation(&root->root_item); |
1510 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), | 1510 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), |
1511 | generation); | 1511 | generation); |
1512 | if (!root->node) { | 1512 | if (IS_ERR(root->node)) { |
1513 | ret = -ENOMEM; | 1513 | ret = PTR_ERR(root->node); |
1514 | goto find_fail; | 1514 | goto find_fail; |
1515 | } else if (!btrfs_buffer_uptodate(root->node, generation, 0)) { | 1515 | } else if (!btrfs_buffer_uptodate(root->node, generation, 0)) { |
1516 | ret = -EIO; | 1516 | ret = -EIO; |
1517 | goto read_fail; | 1517 | free_extent_buffer(root->node); |
1518 | goto find_fail; | ||
1518 | } | 1519 | } |
1519 | root->commit_root = btrfs_root_node(root); | 1520 | root->commit_root = btrfs_root_node(root); |
1520 | out: | 1521 | out: |
1521 | btrfs_free_path(path); | 1522 | btrfs_free_path(path); |
1522 | return root; | 1523 | return root; |
1523 | 1524 | ||
1524 | read_fail: | ||
1525 | free_extent_buffer(root->node); | ||
1526 | find_fail: | 1525 | find_fail: |
1527 | kfree(root); | 1526 | kfree(root); |
1528 | alloc_fail: | 1527 | alloc_fail: |
@@ -1745,7 +1744,7 @@ static void end_workqueue_fn(struct btrfs_work *work) | |||
1745 | bio->bi_private = end_io_wq->private; | 1744 | bio->bi_private = end_io_wq->private; |
1746 | bio->bi_end_io = end_io_wq->end_io; | 1745 | bio->bi_end_io = end_io_wq->end_io; |
1747 | kmem_cache_free(btrfs_end_io_wq_cache, end_io_wq); | 1746 | kmem_cache_free(btrfs_end_io_wq_cache, end_io_wq); |
1748 | bio_endio_nodec(bio, error); | 1747 | bio_endio(bio, error); |
1749 | } | 1748 | } |
1750 | 1749 | ||
1751 | static int cleaner_kthread(void *arg) | 1750 | static int cleaner_kthread(void *arg) |
@@ -2320,8 +2319,12 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info, | |||
2320 | 2319 | ||
2321 | log_tree_root->node = read_tree_block(tree_root, bytenr, | 2320 | log_tree_root->node = read_tree_block(tree_root, bytenr, |
2322 | fs_info->generation + 1); | 2321 | fs_info->generation + 1); |
2323 | if (!log_tree_root->node || | 2322 | if (IS_ERR(log_tree_root->node)) { |
2324 | !extent_buffer_uptodate(log_tree_root->node)) { | 2323 | printk(KERN_ERR "BTRFS: failed to read log tree\n"); |
2324 | ret = PTR_ERR(log_tree_root->node); | ||
2325 | kfree(log_tree_root); | ||
2326 | return ret; | ||
2327 | } else if (!extent_buffer_uptodate(log_tree_root->node)) { | ||
2325 | printk(KERN_ERR "BTRFS: failed to read log tree\n"); | 2328 | printk(KERN_ERR "BTRFS: failed to read log tree\n"); |
2326 | free_extent_buffer(log_tree_root->node); | 2329 | free_extent_buffer(log_tree_root->node); |
2327 | kfree(log_tree_root); | 2330 | kfree(log_tree_root); |
@@ -2494,7 +2497,6 @@ int open_ctree(struct super_block *sb, | |||
2494 | seqlock_init(&fs_info->profiles_lock); | 2497 | seqlock_init(&fs_info->profiles_lock); |
2495 | init_rwsem(&fs_info->delayed_iput_sem); | 2498 | init_rwsem(&fs_info->delayed_iput_sem); |
2496 | 2499 | ||
2497 | init_completion(&fs_info->kobj_unregister); | ||
2498 | INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); | 2500 | INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); |
2499 | INIT_LIST_HEAD(&fs_info->space_info); | 2501 | INIT_LIST_HEAD(&fs_info->space_info); |
2500 | INIT_LIST_HEAD(&fs_info->tree_mod_seq_list); | 2502 | INIT_LIST_HEAD(&fs_info->tree_mod_seq_list); |
@@ -2797,8 +2799,8 @@ int open_ctree(struct super_block *sb, | |||
2797 | chunk_root->node = read_tree_block(chunk_root, | 2799 | chunk_root->node = read_tree_block(chunk_root, |
2798 | btrfs_super_chunk_root(disk_super), | 2800 | btrfs_super_chunk_root(disk_super), |
2799 | generation); | 2801 | generation); |
2800 | if (!chunk_root->node || | 2802 | if (IS_ERR(chunk_root->node) || |
2801 | !test_bit(EXTENT_BUFFER_UPTODATE, &chunk_root->node->bflags)) { | 2803 | !extent_buffer_uptodate(chunk_root->node)) { |
2802 | printk(KERN_ERR "BTRFS: failed to read chunk root on %s\n", | 2804 | printk(KERN_ERR "BTRFS: failed to read chunk root on %s\n", |
2803 | sb->s_id); | 2805 | sb->s_id); |
2804 | goto fail_tree_roots; | 2806 | goto fail_tree_roots; |
@@ -2834,8 +2836,8 @@ retry_root_backup: | |||
2834 | tree_root->node = read_tree_block(tree_root, | 2836 | tree_root->node = read_tree_block(tree_root, |
2835 | btrfs_super_root(disk_super), | 2837 | btrfs_super_root(disk_super), |
2836 | generation); | 2838 | generation); |
2837 | if (!tree_root->node || | 2839 | if (IS_ERR(tree_root->node) || |
2838 | !test_bit(EXTENT_BUFFER_UPTODATE, &tree_root->node->bflags)) { | 2840 | !extent_buffer_uptodate(tree_root->node)) { |
2839 | printk(KERN_WARNING "BTRFS: failed to read tree root on %s\n", | 2841 | printk(KERN_WARNING "BTRFS: failed to read tree root on %s\n", |
2840 | sb->s_id); | 2842 | sb->s_id); |
2841 | 2843 | ||
@@ -2874,10 +2876,22 @@ retry_root_backup: | |||
2874 | 2876 | ||
2875 | btrfs_close_extra_devices(fs_devices, 1); | 2877 | btrfs_close_extra_devices(fs_devices, 1); |
2876 | 2878 | ||
2879 | ret = btrfs_sysfs_add_fsid(fs_devices, NULL); | ||
2880 | if (ret) { | ||
2881 | pr_err("BTRFS: failed to init sysfs fsid interface: %d\n", ret); | ||
2882 | goto fail_block_groups; | ||
2883 | } | ||
2884 | |||
2885 | ret = btrfs_sysfs_add_device(fs_devices); | ||
2886 | if (ret) { | ||
2887 | pr_err("BTRFS: failed to init sysfs device interface: %d\n", ret); | ||
2888 | goto fail_fsdev_sysfs; | ||
2889 | } | ||
2890 | |||
2877 | ret = btrfs_sysfs_add_one(fs_info); | 2891 | ret = btrfs_sysfs_add_one(fs_info); |
2878 | if (ret) { | 2892 | if (ret) { |
2879 | pr_err("BTRFS: failed to init sysfs interface: %d\n", ret); | 2893 | pr_err("BTRFS: failed to init sysfs interface: %d\n", ret); |
2880 | goto fail_block_groups; | 2894 | goto fail_fsdev_sysfs; |
2881 | } | 2895 | } |
2882 | 2896 | ||
2883 | ret = btrfs_init_space_info(fs_info); | 2897 | ret = btrfs_init_space_info(fs_info); |
@@ -3055,6 +3069,9 @@ fail_cleaner: | |||
3055 | fail_sysfs: | 3069 | fail_sysfs: |
3056 | btrfs_sysfs_remove_one(fs_info); | 3070 | btrfs_sysfs_remove_one(fs_info); |
3057 | 3071 | ||
3072 | fail_fsdev_sysfs: | ||
3073 | btrfs_sysfs_remove_fsid(fs_info->fs_devices); | ||
3074 | |||
3058 | fail_block_groups: | 3075 | fail_block_groups: |
3059 | btrfs_put_block_group_cache(fs_info); | 3076 | btrfs_put_block_group_cache(fs_info); |
3060 | btrfs_free_block_groups(fs_info); | 3077 | btrfs_free_block_groups(fs_info); |
@@ -3269,11 +3286,8 @@ static int write_dev_supers(struct btrfs_device *device, | |||
3269 | */ | 3286 | */ |
3270 | static void btrfs_end_empty_barrier(struct bio *bio, int err) | 3287 | static void btrfs_end_empty_barrier(struct bio *bio, int err) |
3271 | { | 3288 | { |
3272 | if (err) { | 3289 | if (err) |
3273 | if (err == -EOPNOTSUPP) | ||
3274 | set_bit(BIO_EOPNOTSUPP, &bio->bi_flags); | ||
3275 | clear_bit(BIO_UPTODATE, &bio->bi_flags); | 3290 | clear_bit(BIO_UPTODATE, &bio->bi_flags); |
3276 | } | ||
3277 | if (bio->bi_private) | 3291 | if (bio->bi_private) |
3278 | complete(bio->bi_private); | 3292 | complete(bio->bi_private); |
3279 | bio_put(bio); | 3293 | bio_put(bio); |
@@ -3301,11 +3315,7 @@ static int write_dev_flush(struct btrfs_device *device, int wait) | |||
3301 | 3315 | ||
3302 | wait_for_completion(&device->flush_wait); | 3316 | wait_for_completion(&device->flush_wait); |
3303 | 3317 | ||
3304 | if (bio_flagged(bio, BIO_EOPNOTSUPP)) { | 3318 | if (!bio_flagged(bio, BIO_UPTODATE)) { |
3305 | printk_in_rcu("BTRFS: disabling barriers on dev %s\n", | ||
3306 | rcu_str_deref(device->name)); | ||
3307 | device->nobarriers = 1; | ||
3308 | } else if (!bio_flagged(bio, BIO_UPTODATE)) { | ||
3309 | ret = -EIO; | 3319 | ret = -EIO; |
3310 | btrfs_dev_stat_inc_and_print(device, | 3320 | btrfs_dev_stat_inc_and_print(device, |
3311 | BTRFS_DEV_STAT_FLUSH_ERRS); | 3321 | BTRFS_DEV_STAT_FLUSH_ERRS); |
@@ -3732,6 +3742,7 @@ void close_ctree(struct btrfs_root *root) | |||
3732 | } | 3742 | } |
3733 | 3743 | ||
3734 | btrfs_sysfs_remove_one(fs_info); | 3744 | btrfs_sysfs_remove_one(fs_info); |
3745 | btrfs_sysfs_remove_fsid(fs_info->fs_devices); | ||
3735 | 3746 | ||
3736 | btrfs_free_fs_roots(fs_info); | 3747 | btrfs_free_fs_roots(fs_info); |
3737 | 3748 | ||
@@ -4060,6 +4071,7 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, | |||
4060 | 4071 | ||
4061 | while ((node = rb_first(&delayed_refs->href_root)) != NULL) { | 4072 | while ((node = rb_first(&delayed_refs->href_root)) != NULL) { |
4062 | struct btrfs_delayed_ref_head *head; | 4073 | struct btrfs_delayed_ref_head *head; |
4074 | struct btrfs_delayed_ref_node *tmp; | ||
4063 | bool pin_bytes = false; | 4075 | bool pin_bytes = false; |
4064 | 4076 | ||
4065 | head = rb_entry(node, struct btrfs_delayed_ref_head, | 4077 | head = rb_entry(node, struct btrfs_delayed_ref_head, |
@@ -4075,11 +4087,10 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, | |||
4075 | continue; | 4087 | continue; |
4076 | } | 4088 | } |
4077 | spin_lock(&head->lock); | 4089 | spin_lock(&head->lock); |
4078 | while ((node = rb_first(&head->ref_root)) != NULL) { | 4090 | list_for_each_entry_safe_reverse(ref, tmp, &head->ref_list, |
4079 | ref = rb_entry(node, struct btrfs_delayed_ref_node, | 4091 | list) { |
4080 | rb_node); | ||
4081 | ref->in_tree = 0; | 4092 | ref->in_tree = 0; |
4082 | rb_erase(&ref->rb_node, &head->ref_root); | 4093 | list_del(&ref->list); |
4083 | atomic_dec(&delayed_refs->num_entries); | 4094 | atomic_dec(&delayed_refs->num_entries); |
4084 | btrfs_put_delayed_ref(ref); | 4095 | btrfs_put_delayed_ref(ref); |
4085 | } | 4096 | } |