diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
| -rw-r--r-- | fs/btrfs/disk-io.c | 59 |
1 files changed, 26 insertions, 33 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index a7ffc88a7dbe..7ae51decf6d3 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -1153,7 +1153,6 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
| 1153 | root->orphan_block_rsv = NULL; | 1153 | root->orphan_block_rsv = NULL; |
| 1154 | 1154 | ||
| 1155 | INIT_LIST_HEAD(&root->dirty_list); | 1155 | INIT_LIST_HEAD(&root->dirty_list); |
| 1156 | INIT_LIST_HEAD(&root->orphan_list); | ||
| 1157 | INIT_LIST_HEAD(&root->root_list); | 1156 | INIT_LIST_HEAD(&root->root_list); |
| 1158 | spin_lock_init(&root->orphan_lock); | 1157 | spin_lock_init(&root->orphan_lock); |
| 1159 | spin_lock_init(&root->inode_lock); | 1158 | spin_lock_init(&root->inode_lock); |
| @@ -1166,6 +1165,7 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
| 1166 | atomic_set(&root->log_commit[0], 0); | 1165 | atomic_set(&root->log_commit[0], 0); |
| 1167 | atomic_set(&root->log_commit[1], 0); | 1166 | atomic_set(&root->log_commit[1], 0); |
| 1168 | atomic_set(&root->log_writers, 0); | 1167 | atomic_set(&root->log_writers, 0); |
| 1168 | atomic_set(&root->orphan_inodes, 0); | ||
| 1169 | root->log_batch = 0; | 1169 | root->log_batch = 0; |
| 1170 | root->log_transid = 0; | 1170 | root->log_transid = 0; |
| 1171 | root->last_log_commit = 0; | 1171 | root->last_log_commit = 0; |
| @@ -1252,7 +1252,7 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, | |||
| 1252 | 1252 | ||
| 1253 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, | 1253 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, |
| 1254 | BTRFS_TREE_LOG_OBJECTID, NULL, | 1254 | BTRFS_TREE_LOG_OBJECTID, NULL, |
| 1255 | 0, 0, 0, 0); | 1255 | 0, 0, 0); |
| 1256 | if (IS_ERR(leaf)) { | 1256 | if (IS_ERR(leaf)) { |
| 1257 | kfree(root); | 1257 | kfree(root); |
| 1258 | return ERR_CAST(leaf); | 1258 | return ERR_CAST(leaf); |
| @@ -1914,11 +1914,14 @@ int open_ctree(struct super_block *sb, | |||
| 1914 | spin_lock_init(&fs_info->delayed_iput_lock); | 1914 | spin_lock_init(&fs_info->delayed_iput_lock); |
| 1915 | spin_lock_init(&fs_info->defrag_inodes_lock); | 1915 | spin_lock_init(&fs_info->defrag_inodes_lock); |
| 1916 | spin_lock_init(&fs_info->free_chunk_lock); | 1916 | spin_lock_init(&fs_info->free_chunk_lock); |
| 1917 | spin_lock_init(&fs_info->tree_mod_seq_lock); | ||
| 1918 | rwlock_init(&fs_info->tree_mod_log_lock); | ||
| 1917 | mutex_init(&fs_info->reloc_mutex); | 1919 | mutex_init(&fs_info->reloc_mutex); |
| 1918 | 1920 | ||
| 1919 | init_completion(&fs_info->kobj_unregister); | 1921 | init_completion(&fs_info->kobj_unregister); |
| 1920 | INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); | 1922 | INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); |
| 1921 | INIT_LIST_HEAD(&fs_info->space_info); | 1923 | INIT_LIST_HEAD(&fs_info->space_info); |
| 1924 | INIT_LIST_HEAD(&fs_info->tree_mod_seq_list); | ||
| 1922 | btrfs_mapping_init(&fs_info->mapping_tree); | 1925 | btrfs_mapping_init(&fs_info->mapping_tree); |
| 1923 | btrfs_init_block_rsv(&fs_info->global_block_rsv); | 1926 | btrfs_init_block_rsv(&fs_info->global_block_rsv); |
| 1924 | btrfs_init_block_rsv(&fs_info->delalloc_block_rsv); | 1927 | btrfs_init_block_rsv(&fs_info->delalloc_block_rsv); |
| @@ -1931,12 +1934,14 @@ int open_ctree(struct super_block *sb, | |||
| 1931 | atomic_set(&fs_info->async_submit_draining, 0); | 1934 | atomic_set(&fs_info->async_submit_draining, 0); |
| 1932 | atomic_set(&fs_info->nr_async_bios, 0); | 1935 | atomic_set(&fs_info->nr_async_bios, 0); |
| 1933 | atomic_set(&fs_info->defrag_running, 0); | 1936 | atomic_set(&fs_info->defrag_running, 0); |
| 1937 | atomic_set(&fs_info->tree_mod_seq, 0); | ||
| 1934 | fs_info->sb = sb; | 1938 | fs_info->sb = sb; |
| 1935 | fs_info->max_inline = 8192 * 1024; | 1939 | fs_info->max_inline = 8192 * 1024; |
| 1936 | fs_info->metadata_ratio = 0; | 1940 | fs_info->metadata_ratio = 0; |
| 1937 | fs_info->defrag_inodes = RB_ROOT; | 1941 | fs_info->defrag_inodes = RB_ROOT; |
| 1938 | fs_info->trans_no_join = 0; | 1942 | fs_info->trans_no_join = 0; |
| 1939 | fs_info->free_chunk_space = 0; | 1943 | fs_info->free_chunk_space = 0; |
| 1944 | fs_info->tree_mod_log = RB_ROOT; | ||
| 1940 | 1945 | ||
| 1941 | /* readahead state */ | 1946 | /* readahead state */ |
| 1942 | INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT); | 1947 | INIT_RADIX_TREE(&fs_info->reada_tree, GFP_NOFS & ~__GFP_WAIT); |
| @@ -2001,7 +2006,8 @@ int open_ctree(struct super_block *sb, | |||
| 2001 | BTRFS_I(fs_info->btree_inode)->root = tree_root; | 2006 | BTRFS_I(fs_info->btree_inode)->root = tree_root; |
| 2002 | memset(&BTRFS_I(fs_info->btree_inode)->location, 0, | 2007 | memset(&BTRFS_I(fs_info->btree_inode)->location, 0, |
| 2003 | sizeof(struct btrfs_key)); | 2008 | sizeof(struct btrfs_key)); |
| 2004 | BTRFS_I(fs_info->btree_inode)->dummy_inode = 1; | 2009 | set_bit(BTRFS_INODE_DUMMY, |
| 2010 | &BTRFS_I(fs_info->btree_inode)->runtime_flags); | ||
| 2005 | insert_inode_hash(fs_info->btree_inode); | 2011 | insert_inode_hash(fs_info->btree_inode); |
| 2006 | 2012 | ||
| 2007 | spin_lock_init(&fs_info->block_group_cache_lock); | 2013 | spin_lock_init(&fs_info->block_group_cache_lock); |
| @@ -2353,6 +2359,13 @@ retry_root_backup: | |||
| 2353 | fs_info->generation = generation; | 2359 | fs_info->generation = generation; |
| 2354 | fs_info->last_trans_committed = generation; | 2360 | fs_info->last_trans_committed = generation; |
| 2355 | 2361 | ||
| 2362 | ret = btrfs_init_dev_stats(fs_info); | ||
| 2363 | if (ret) { | ||
| 2364 | printk(KERN_ERR "btrfs: failed to init dev_stats: %d\n", | ||
| 2365 | ret); | ||
| 2366 | goto fail_block_groups; | ||
| 2367 | } | ||
| 2368 | |||
| 2356 | ret = btrfs_init_space_info(fs_info); | 2369 | ret = btrfs_init_space_info(fs_info); |
| 2357 | if (ret) { | 2370 | if (ret) { |
| 2358 | printk(KERN_ERR "Failed to initial space info: %d\n", ret); | 2371 | printk(KERN_ERR "Failed to initial space info: %d\n", ret); |
| @@ -2556,18 +2569,19 @@ recovery_tree_root: | |||
| 2556 | 2569 | ||
| 2557 | static void btrfs_end_buffer_write_sync(struct buffer_head *bh, int uptodate) | 2570 | static void btrfs_end_buffer_write_sync(struct buffer_head *bh, int uptodate) |
| 2558 | { | 2571 | { |
| 2559 | char b[BDEVNAME_SIZE]; | ||
| 2560 | |||
| 2561 | if (uptodate) { | 2572 | if (uptodate) { |
| 2562 | set_buffer_uptodate(bh); | 2573 | set_buffer_uptodate(bh); |
| 2563 | } else { | 2574 | } else { |
| 2575 | struct btrfs_device *device = (struct btrfs_device *) | ||
| 2576 | bh->b_private; | ||
| 2577 | |||
| 2564 | printk_ratelimited(KERN_WARNING "lost page write due to " | 2578 | printk_ratelimited(KERN_WARNING "lost page write due to " |
| 2565 | "I/O error on %s\n", | 2579 | "I/O error on %s\n", device->name); |
| 2566 | bdevname(bh->b_bdev, b)); | ||
| 2567 | /* note, we dont' set_buffer_write_io_error because we have | 2580 | /* note, we dont' set_buffer_write_io_error because we have |
| 2568 | * our own ways of dealing with the IO errors | 2581 | * our own ways of dealing with the IO errors |
| 2569 | */ | 2582 | */ |
| 2570 | clear_buffer_uptodate(bh); | 2583 | clear_buffer_uptodate(bh); |
| 2584 | btrfs_dev_stat_inc_and_print(device, BTRFS_DEV_STAT_WRITE_ERRS); | ||
| 2571 | } | 2585 | } |
| 2572 | unlock_buffer(bh); | 2586 | unlock_buffer(bh); |
| 2573 | put_bh(bh); | 2587 | put_bh(bh); |
| @@ -2682,6 +2696,7 @@ static int write_dev_supers(struct btrfs_device *device, | |||
| 2682 | set_buffer_uptodate(bh); | 2696 | set_buffer_uptodate(bh); |
| 2683 | lock_buffer(bh); | 2697 | lock_buffer(bh); |
| 2684 | bh->b_end_io = btrfs_end_buffer_write_sync; | 2698 | bh->b_end_io = btrfs_end_buffer_write_sync; |
| 2699 | bh->b_private = device; | ||
| 2685 | } | 2700 | } |
| 2686 | 2701 | ||
| 2687 | /* | 2702 | /* |
| @@ -2740,6 +2755,9 @@ static int write_dev_flush(struct btrfs_device *device, int wait) | |||
| 2740 | } | 2755 | } |
| 2741 | if (!bio_flagged(bio, BIO_UPTODATE)) { | 2756 | if (!bio_flagged(bio, BIO_UPTODATE)) { |
| 2742 | ret = -EIO; | 2757 | ret = -EIO; |
| 2758 | if (!bio_flagged(bio, BIO_EOPNOTSUPP)) | ||
| 2759 | btrfs_dev_stat_inc_and_print(device, | ||
| 2760 | BTRFS_DEV_STAT_FLUSH_ERRS); | ||
| 2743 | } | 2761 | } |
| 2744 | 2762 | ||
| 2745 | /* drop the reference from the wait == 0 run */ | 2763 | /* drop the reference from the wait == 0 run */ |
| @@ -2753,7 +2771,7 @@ static int write_dev_flush(struct btrfs_device *device, int wait) | |||
| 2753 | * one reference for us, and we leave it for the | 2771 | * one reference for us, and we leave it for the |
| 2754 | * caller | 2772 | * caller |
| 2755 | */ | 2773 | */ |
| 2756 | device->flush_bio = NULL;; | 2774 | device->flush_bio = NULL; |
| 2757 | bio = bio_alloc(GFP_NOFS, 0); | 2775 | bio = bio_alloc(GFP_NOFS, 0); |
| 2758 | if (!bio) | 2776 | if (!bio) |
| 2759 | return -ENOMEM; | 2777 | return -ENOMEM; |
| @@ -2902,19 +2920,6 @@ int write_ctree_super(struct btrfs_trans_handle *trans, | |||
| 2902 | return ret; | 2920 | return ret; |
| 2903 | } | 2921 | } |
| 2904 | 2922 | ||
| 2905 | /* Kill all outstanding I/O */ | ||
| 2906 | void btrfs_abort_devices(struct btrfs_root *root) | ||
| 2907 | { | ||
| 2908 | struct list_head *head; | ||
| 2909 | struct btrfs_device *dev; | ||
| 2910 | mutex_lock(&root->fs_info->fs_devices->device_list_mutex); | ||
| 2911 | head = &root->fs_info->fs_devices->devices; | ||
| 2912 | list_for_each_entry_rcu(dev, head, dev_list) { | ||
| 2913 | blk_abort_queue(dev->bdev->bd_disk->queue); | ||
| 2914 | } | ||
| 2915 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); | ||
| 2916 | } | ||
| 2917 | |||
| 2918 | void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) | 2923 | void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) |
| 2919 | { | 2924 | { |
| 2920 | spin_lock(&fs_info->fs_roots_radix_lock); | 2925 | spin_lock(&fs_info->fs_roots_radix_lock); |
| @@ -3671,17 +3676,6 @@ int btrfs_cleanup_transaction(struct btrfs_root *root) | |||
| 3671 | return 0; | 3676 | return 0; |
| 3672 | } | 3677 | } |
| 3673 | 3678 | ||
| 3674 | static int btree_writepage_io_failed_hook(struct bio *bio, struct page *page, | ||
| 3675 | u64 start, u64 end, | ||
| 3676 | struct extent_state *state) | ||
| 3677 | { | ||
| 3678 | struct super_block *sb = page->mapping->host->i_sb; | ||
| 3679 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); | ||
| 3680 | btrfs_error(fs_info, -EIO, | ||
| 3681 | "Error occured while writing out btree at %llu", start); | ||
| 3682 | return -EIO; | ||
| 3683 | } | ||
| 3684 | |||
| 3685 | static struct extent_io_ops btree_extent_io_ops = { | 3679 | static struct extent_io_ops btree_extent_io_ops = { |
| 3686 | .write_cache_pages_lock_hook = btree_lock_page_hook, | 3680 | .write_cache_pages_lock_hook = btree_lock_page_hook, |
| 3687 | .readpage_end_io_hook = btree_readpage_end_io_hook, | 3681 | .readpage_end_io_hook = btree_readpage_end_io_hook, |
| @@ -3689,5 +3683,4 @@ static struct extent_io_ops btree_extent_io_ops = { | |||
| 3689 | .submit_bio_hook = btree_submit_bio_hook, | 3683 | .submit_bio_hook = btree_submit_bio_hook, |
| 3690 | /* note we're sharing with inode.c for the merge bio hook */ | 3684 | /* note we're sharing with inode.c for the merge bio hook */ |
| 3691 | .merge_bio_hook = btrfs_merge_bio_hook, | 3685 | .merge_bio_hook = btrfs_merge_bio_hook, |
| 3692 | .writepage_io_failed_hook = btree_writepage_io_failed_hook, | ||
| 3693 | }; | 3686 | }; |
