diff options
author | Josef Bacik <josef@redhat.com> | 2010-12-03 13:17:53 -0500 |
---|---|---|
committer | Josef Bacik <josef@redhat.com> | 2010-12-09 13:57:12 -0500 |
commit | 2b20982e3154266106573beac2a4d4ba57a2789a (patch) | |
tree | 13539703ccb713385b4c7ff7eac508bb8f3b1e18 /fs | |
parent | 955256f2c3e25c94ad373c43fbc38d2ac8af2a71 (diff) |
Btrfs: deal with space cache errors better
Currently if the space cache inode generation number doesn't match the
generation number in the space cache header we will just fail to load the space
cache, but we won't mark the space cache as an error, so we'll keep getting that
error each time somebody tries to cache that block group until we actually clear
the thing. Fix this by marking the space cache as having an error so we only
get the message once. This patch also makes it so that we don't try and setup
space cache for a block group that isn't cached, since we won't be able to write
it out anyway. None of these problems are actual problems, they are just
annoying and sub-optimal. Thanks,
Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 10 | ||||
-rw-r--r-- | fs/btrfs/free-space-cache.c | 12 |
2 files changed, 13 insertions, 9 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index ddaf6340fe7f..8c56f5b38948 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -2742,6 +2742,7 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group, | |||
2742 | struct btrfs_root *root = block_group->fs_info->tree_root; | 2742 | struct btrfs_root *root = block_group->fs_info->tree_root; |
2743 | struct inode *inode = NULL; | 2743 | struct inode *inode = NULL; |
2744 | u64 alloc_hint = 0; | 2744 | u64 alloc_hint = 0; |
2745 | int dcs = BTRFS_DC_ERROR; | ||
2745 | int num_pages = 0; | 2746 | int num_pages = 0; |
2746 | int retries = 0; | 2747 | int retries = 0; |
2747 | int ret = 0; | 2748 | int ret = 0; |
@@ -2796,6 +2797,8 @@ again: | |||
2796 | 2797 | ||
2797 | spin_lock(&block_group->lock); | 2798 | spin_lock(&block_group->lock); |
2798 | if (block_group->cached != BTRFS_CACHE_FINISHED) { | 2799 | if (block_group->cached != BTRFS_CACHE_FINISHED) { |
2800 | /* We're not cached, don't bother trying to write stuff out */ | ||
2801 | dcs = BTRFS_DC_WRITTEN; | ||
2799 | spin_unlock(&block_group->lock); | 2802 | spin_unlock(&block_group->lock); |
2800 | goto out_put; | 2803 | goto out_put; |
2801 | } | 2804 | } |
@@ -2822,6 +2825,8 @@ again: | |||
2822 | ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages, | 2825 | ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages, |
2823 | num_pages, num_pages, | 2826 | num_pages, num_pages, |
2824 | &alloc_hint); | 2827 | &alloc_hint); |
2828 | if (!ret) | ||
2829 | dcs = BTRFS_DC_SETUP; | ||
2825 | btrfs_free_reserved_data_space(inode, num_pages); | 2830 | btrfs_free_reserved_data_space(inode, num_pages); |
2826 | out_put: | 2831 | out_put: |
2827 | iput(inode); | 2832 | iput(inode); |
@@ -2829,10 +2834,7 @@ out_free: | |||
2829 | btrfs_release_path(root, path); | 2834 | btrfs_release_path(root, path); |
2830 | out: | 2835 | out: |
2831 | spin_lock(&block_group->lock); | 2836 | spin_lock(&block_group->lock); |
2832 | if (ret) | 2837 | block_group->disk_cache_state = dcs; |
2833 | block_group->disk_cache_state = BTRFS_DC_ERROR; | ||
2834 | else | ||
2835 | block_group->disk_cache_state = BTRFS_DC_SETUP; | ||
2836 | spin_unlock(&block_group->lock); | 2838 | spin_unlock(&block_group->lock); |
2837 | 2839 | ||
2838 | return ret; | 2840 | return ret; |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 22ee0dc2e6b8..60d684266959 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -290,7 +290,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, | |||
290 | (unsigned long long)BTRFS_I(inode)->generation, | 290 | (unsigned long long)BTRFS_I(inode)->generation, |
291 | (unsigned long long)generation, | 291 | (unsigned long long)generation, |
292 | (unsigned long long)block_group->key.objectid); | 292 | (unsigned long long)block_group->key.objectid); |
293 | goto out; | 293 | goto free_cache; |
294 | } | 294 | } |
295 | 295 | ||
296 | if (!num_entries) | 296 | if (!num_entries) |
@@ -524,6 +524,12 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
524 | return 0; | 524 | return 0; |
525 | } | 525 | } |
526 | 526 | ||
527 | node = rb_first(&block_group->free_space_offset); | ||
528 | if (!node) { | ||
529 | iput(inode); | ||
530 | return 0; | ||
531 | } | ||
532 | |||
527 | last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT; | 533 | last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT; |
528 | filemap_write_and_wait(inode->i_mapping); | 534 | filemap_write_and_wait(inode->i_mapping); |
529 | btrfs_wait_ordered_range(inode, inode->i_size & | 535 | btrfs_wait_ordered_range(inode, inode->i_size & |
@@ -543,10 +549,6 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
543 | */ | 549 | */ |
544 | first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64); | 550 | first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64); |
545 | 551 | ||
546 | node = rb_first(&block_group->free_space_offset); | ||
547 | if (!node) | ||
548 | goto out_free; | ||
549 | |||
550 | /* | 552 | /* |
551 | * Lock all pages first so we can lock the extent safely. | 553 | * Lock all pages first so we can lock the extent safely. |
552 | * | 554 | * |