OSDN Git Service

Revert "Btrfs: rework the overcommit logic to be based on the total size"
[android-x86/kernel.git] / fs / btrfs / extent-tree.c
index f1c1694..07f7f69 100644 (file)
@@ -2440,6 +2440,8 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
                        default:
                                WARN_ON(1);
                        }
+               } else {
+                       list_del_init(&locked_ref->cluster);
                }
                spin_unlock(&delayed_refs->lock);
 
@@ -2462,7 +2464,6 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
                 * list before we release it.
                 */
                if (btrfs_delayed_ref_is_head(ref)) {
-                       list_del_init(&locked_ref->cluster);
                        btrfs_delayed_ref_unlock(locked_ref);
                        locked_ref = NULL;
                }
@@ -3924,7 +3925,6 @@ static int can_overcommit(struct btrfs_root *root,
        u64 space_size;
        u64 avail;
        u64 used;
-       u64 to_add;
 
        used = space_info->bytes_used + space_info->bytes_reserved +
                space_info->bytes_pinned + space_info->bytes_readonly;
@@ -3958,25 +3958,17 @@ static int can_overcommit(struct btrfs_root *root,
                       BTRFS_BLOCK_GROUP_RAID10))
                avail >>= 1;
 
-       to_add = space_info->total_bytes;
-
        /*
         * If we aren't flushing all things, let us overcommit up to
         * 1/2th of the space. If we can flush, don't let us overcommit
         * too much, let it overcommit up to 1/8 of the space.
         */
        if (flush == BTRFS_RESERVE_FLUSH_ALL)
-               to_add >>= 3;
+               avail >>= 3;
        else
-               to_add >>= 1;
-
-       /*
-        * Limit the overcommit to the amount of free space we could possibly
-        * allocate for chunks.
-        */
-       to_add = min(avail, to_add);
+               avail >>= 1;
 
-       if (used + bytes < space_info->total_bytes + to_add)
+       if (used + bytes < space_info->total_bytes + avail)
                return 1;
        return 0;
 }
@@ -4361,6 +4353,9 @@ static struct btrfs_block_rsv *get_block_rsv(
        if (root == root->fs_info->csum_root && trans->adding_csums)
                block_rsv = trans->block_rsv;
 
+       if (root == root->fs_info->uuid_root)
+               block_rsv = trans->block_rsv;
+
        if (!block_rsv)
                block_rsv = root->block_rsv;
 
@@ -5715,7 +5710,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
 
                        if (ret) {
                                btrfs_err(info, "umm, got %d back from search, was looking for %llu",
-                                       ret, (unsigned long long)bytenr);
+                                       ret, bytenr);
                                if (ret > 0)
                                        btrfs_print_leaf(extent_root,
                                                         path->nodes[0]);
@@ -5731,11 +5726,8 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                WARN_ON(1);
                btrfs_err(info,
                        "unable to find ref byte nr %llu parent %llu root %llu  owner %llu offset %llu",
-                       (unsigned long long)bytenr,
-                       (unsigned long long)parent,
-                       (unsigned long long)root_objectid,
-                       (unsigned long long)owner_objectid,
-                       (unsigned long long)owner_offset);
+                       bytenr, parent, root_objectid, owner_objectid,
+                       owner_offset);
        } else {
                btrfs_abort_transaction(trans, extent_root, ret);
                goto out;
@@ -5764,7 +5756,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
                                        -1, 1);
                if (ret) {
                        btrfs_err(info, "umm, got %d back from search, was looking for %llu",
-                               ret, (unsigned long long)bytenr);
+                               ret, bytenr);
                        btrfs_print_leaf(extent_root, path->nodes[0]);
                }
                if (ret < 0) {
@@ -6116,10 +6108,13 @@ enum btrfs_loop_type {
 /*
  * walks the btree of allocated extents and find a hole of a given size.
  * The key ins is changed to record the hole:
- * ins->objectid == block start
+ * ins->objectid == start position
  * ins->flags = BTRFS_EXTENT_ITEM_KEY
- * ins->offset == number of blocks
+ * ins->offset == the size of the hole.
  * Any available blocks before search_start are skipped.
+ *
+ * If there is no suitable free space, we will record the max size of
+ * the free space extent currently.
  */
 static noinline int find_free_extent(struct btrfs_root *orig_root,
                                     u64 num_bytes, u64 empty_size,
@@ -6132,6 +6127,7 @@ static noinline int find_free_extent(struct btrfs_root *orig_root,
        struct btrfs_block_group_cache *block_group = NULL;
        struct btrfs_block_group_cache *used_block_group;
        u64 search_start = 0;
+       u64 max_extent_size = 0;
        int empty_cluster = 2 * 1024 * 1024;
        struct btrfs_space_info *space_info;
        int loop = 0;
@@ -6291,7 +6287,10 @@ have_block_group:
                                btrfs_get_block_group(used_block_group);
 
                        offset = btrfs_alloc_from_cluster(used_block_group,
-                         last_ptr, num_bytes, used_block_group->key.objectid);
+                                               last_ptr,
+                                               num_bytes,
+                                               used_block_group->key.objectid,
+                                               &max_extent_size);
                        if (offset) {
                                /* we have a block, we're done */
                                spin_unlock(&last_ptr->refill_lock);
@@ -6354,8 +6353,10 @@ refill_cluster:
                                 * cluster
                                 */
                                offset = btrfs_alloc_from_cluster(block_group,
-                                                 last_ptr, num_bytes,
-                                                 search_start);
+                                                       last_ptr,
+                                                       num_bytes,
+                                                       search_start,
+                                                       &max_extent_size);
                                if (offset) {
                                        /* we found one, proceed */
                                        spin_unlock(&last_ptr->refill_lock);
@@ -6390,13 +6391,18 @@ unclustered_alloc:
                if (cached &&
                    block_group->free_space_ctl->free_space <
                    num_bytes + empty_cluster + empty_size) {
+                       if (block_group->free_space_ctl->free_space >
+                           max_extent_size)
+                               max_extent_size =
+                                       block_group->free_space_ctl->free_space;
                        spin_unlock(&block_group->free_space_ctl->tree_lock);
                        goto loop;
                }
                spin_unlock(&block_group->free_space_ctl->tree_lock);
 
                offset = btrfs_find_space_for_alloc(block_group, search_start,
-                                                   num_bytes, empty_size);
+                                                   num_bytes, empty_size,
+                                                   &max_extent_size);
                /*
                 * If we didn't find a chunk, and we haven't failed on this
                 * block group before, and this block group is in the middle of
@@ -6514,7 +6520,8 @@ loop:
                ret = 0;
        }
 out:
-
+       if (ret == -ENOSPC)
+               ins->offset = max_extent_size;
        return ret;
 }
 
@@ -6526,19 +6533,15 @@ static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
 
        spin_lock(&info->lock);
        printk(KERN_INFO "space_info %llu has %llu free, is %sfull\n",
-              (unsigned long long)info->flags,
-              (unsigned long long)(info->total_bytes - info->bytes_used -
-                                   info->bytes_pinned - info->bytes_reserved -
-                                   info->bytes_readonly),
+              info->flags,
+              info->total_bytes - info->bytes_used - info->bytes_pinned -
+              info->bytes_reserved - info->bytes_readonly,
               (info->full) ? "" : "not ");
        printk(KERN_INFO "space_info total=%llu, used=%llu, pinned=%llu, "
               "reserved=%llu, may_use=%llu, readonly=%llu\n",
-              (unsigned long long)info->total_bytes,
-              (unsigned long long)info->bytes_used,
-              (unsigned long long)info->bytes_pinned,
-              (unsigned long long)info->bytes_reserved,
-              (unsigned long long)info->bytes_may_use,
-              (unsigned long long)info->bytes_readonly);
+              info->total_bytes, info->bytes_used, info->bytes_pinned,
+              info->bytes_reserved, info->bytes_may_use,
+              info->bytes_readonly);
        spin_unlock(&info->lock);
 
        if (!dump_block_groups)
@@ -6549,12 +6552,9 @@ again:
        list_for_each_entry(cache, &info->block_groups[index], list) {
                spin_lock(&cache->lock);
                printk(KERN_INFO "block group %llu has %llu bytes, %llu used %llu pinned %llu reserved %s\n",
-                      (unsigned long long)cache->key.objectid,
-                      (unsigned long long)cache->key.offset,
-                      (unsigned long long)btrfs_block_group_used(&cache->item),
-                      (unsigned long long)cache->pinned,
-                      (unsigned long long)cache->reserved,
-                      cache->ro ? "[readonly]" : "");
+                      cache->key.objectid, cache->key.offset,
+                      btrfs_block_group_used(&cache->item), cache->pinned,
+                      cache->reserved, cache->ro ? "[readonly]" : "");
                btrfs_dump_free_space(cache, bytes);
                spin_unlock(&cache->lock);
        }
@@ -6579,8 +6579,8 @@ again:
                               flags);
 
        if (ret == -ENOSPC) {
-               if (!final_tried) {
-                       num_bytes = num_bytes >> 1;
+               if (!final_tried && ins->offset) {
+                       num_bytes = min(num_bytes >> 1, ins->offset);
                        num_bytes = round_down(num_bytes, root->sectorsize);
                        num_bytes = max(num_bytes, min_alloc_size);
                        if (num_bytes == min_alloc_size)
@@ -6591,8 +6591,7 @@ again:
 
                        sinfo = __find_space_info(root->fs_info, flags);
                        btrfs_err(root->fs_info, "allocation failed flags %llu, wanted %llu",
-                               (unsigned long long)flags,
-                               (unsigned long long)num_bytes);
+                               flags, num_bytes);
                        if (sinfo)
                                dump_space_info(sinfo, num_bytes, 1);
                }
@@ -6612,7 +6611,7 @@ static int __btrfs_free_reserved_extent(struct btrfs_root *root,
        cache = btrfs_lookup_block_group(root->fs_info, start);
        if (!cache) {
                btrfs_err(root->fs_info, "Unable to find block group for %llu",
-                       (unsigned long long)start);
+                       start);
                return -ENOSPC;
        }
 
@@ -6708,8 +6707,7 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
        ret = update_block_group(root, ins->objectid, ins->offset, 1);
        if (ret) { /* -ENOENT, logic error */
                btrfs_err(fs_info, "update block group failed for %llu %llu",
-                       (unsigned long long)ins->objectid,
-                       (unsigned long long)ins->offset);
+                       ins->objectid, ins->offset);
                BUG();
        }
        return ret;
@@ -6781,8 +6779,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans,
        ret = update_block_group(root, ins->objectid, root->leafsize, 1);
        if (ret) { /* -ENOENT, logic error */
                btrfs_err(fs_info, "update block group failed for %llu %llu",
-                       (unsigned long long)ins->objectid,
-                       (unsigned long long)ins->offset);
+                       ins->objectid, ins->offset);
                BUG();
        }
        return ret;