aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2010-07-02 12:14:14 -0400
committerChris Mason <chris.mason@oracle.com>2010-10-29 09:26:29 -0400
commit0cb59c9953171e9adf6da8142a5c85ceb77bb60d (patch)
treef72af47fa18815491814290a1b4907082bd9316d /fs/btrfs/extent-tree.c
parent0af3d00bad38d3bb9912a60928ad0669f17bdb76 (diff)
Btrfs: write out free space cache
This is a simple bit, just dump the free space cache out to our preallocated inode when we're writing out dirty block groups. There are a bunch of changes in inode.c in order to account for special cases. Mostly when we're doing the writeout we're holding trans_mutex, so we need to use the nolock transacation functions. Also we can't do asynchronous completions since the async thread could be blocked on already completed IO waiting for the transaction lock. This has been tested with xfstests and btrfs filesystem balance, as well as my ENOSPC tests. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index aab40fb3faed..d5455a2bf60b 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2847,6 +2847,8 @@ again:
2847 continue; 2847 continue;
2848 } 2848 }
2849 2849
2850 if (cache->disk_cache_state == BTRFS_DC_SETUP)
2851 cache->disk_cache_state = BTRFS_DC_NEED_WRITE;
2850 cache->dirty = 0; 2852 cache->dirty = 0;
2851 last = cache->key.objectid + cache->key.offset; 2853 last = cache->key.objectid + cache->key.offset;
2852 2854
@@ -2855,6 +2857,52 @@ again:
2855 btrfs_put_block_group(cache); 2857 btrfs_put_block_group(cache);
2856 } 2858 }
2857 2859
2860 while (1) {
2861 /*
2862 * I don't think this is needed since we're just marking our
2863 * preallocated extent as written, but just in case it can't
2864 * hurt.
2865 */
2866 if (last == 0) {
2867 err = btrfs_run_delayed_refs(trans, root,
2868 (unsigned long)-1);
2869 BUG_ON(err);
2870 }
2871
2872 cache = btrfs_lookup_first_block_group(root->fs_info, last);
2873 while (cache) {
2874 /*
2875 * Really this shouldn't happen, but it could if we
2876 * couldn't write the entire preallocated extent and
2877 * splitting the extent resulted in a new block.
2878 */
2879 if (cache->dirty) {
2880 btrfs_put_block_group(cache);
2881 goto again;
2882 }
2883 if (cache->disk_cache_state == BTRFS_DC_NEED_WRITE)
2884 break;
2885 cache = next_block_group(root, cache);
2886 }
2887 if (!cache) {
2888 if (last == 0)
2889 break;
2890 last = 0;
2891 continue;
2892 }
2893
2894 btrfs_write_out_cache(root, trans, cache, path);
2895
2896 /*
2897 * If we didn't have an error then the cache state is still
2898 * NEED_WRITE, so we can set it to WRITTEN.
2899 */
2900 if (cache->disk_cache_state == BTRFS_DC_NEED_WRITE)
2901 cache->disk_cache_state = BTRFS_DC_WRITTEN;
2902 last = cache->key.objectid + cache->key.offset;
2903 btrfs_put_block_group(cache);
2904 }
2905
2858 btrfs_free_path(path); 2906 btrfs_free_path(path);
2859 return 0; 2907 return 0;
2860} 2908}