]> nv-tegra.nvidia Code Review - linux-2.6.git/blobdiff - fs/btrfs/extent-tree.c
Btrfs: Add a clear_cache mount option
[linux-2.6.git] / fs / btrfs / extent-tree.c
index 5c9ef3ac25e1416846d04690225c45bd9f871257..1a94ee4c4fbbc5c78a78bd8ce91b181bdeeba6b6 100644 (file)
@@ -547,7 +547,7 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info,
 
        rcu_read_lock();
        list_for_each_entry_rcu(found, head, list) {
-               if (found->flags == flags) {
+               if (found->flags & flags) {
                        rcu_read_unlock();
                        return found;
                }
@@ -3266,6 +3266,13 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
        }
        spin_unlock(&space_info->lock);
 
+       /*
+        * If we have mixed data/metadata chunks we want to make sure we keep
+        * allocating mixed chunks instead of individual chunks.
+        */
+       if (btrfs_mixed_space_info(space_info))
+               flags |= (BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA);
+
        /*
         * if we're doing a data chunk, go ahead and make sure that
         * we keep a reasonable number of metadata chunks allocated in the
@@ -4787,6 +4794,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
        bool found_uncached_bg = false;
        bool failed_cluster_refill = false;
        bool failed_alloc = false;
+       bool use_cluster = true;
        u64 ideal_cache_percent = 0;
        u64 ideal_cache_offset = 0;
 
@@ -4801,16 +4809,24 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
                return -ENOSPC;
        }
 
+       /*
+        * If the space info is for both data and metadata it means we have a
+        * small filesystem and we can't use the clustering stuff.
+        */
+       if (btrfs_mixed_space_info(space_info))
+               use_cluster = false;
+
        if (orig_root->ref_cows || empty_size)
                allowed_chunk_alloc = 1;
 
-       if (data & BTRFS_BLOCK_GROUP_METADATA) {
+       if (data & BTRFS_BLOCK_GROUP_METADATA && use_cluster) {
                last_ptr = &root->fs_info->meta_alloc_cluster;
                if (!btrfs_test_opt(root, SSD))
                        empty_cluster = 64 * 1024;
        }
 
-       if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) {
+       if ((data & BTRFS_BLOCK_GROUP_DATA) && use_cluster &&
+           btrfs_test_opt(root, SSD)) {
                last_ptr = &root->fs_info->data_alloc_cluster;
        }
 
@@ -8182,6 +8198,8 @@ int btrfs_read_block_groups(struct btrfs_root *root)
        if (cache_gen != 0 &&
            btrfs_super_generation(&root->fs_info->super_copy) != cache_gen)
                need_clear = 1;
+       if (btrfs_test_opt(root, CLEAR_CACHE))
+               need_clear = 1;
 
        while (1) {
                ret = find_first_block_group(root, path, &key);