btrfs: set max_extent_size properly
authorJosef Bacik <jbacik@fb.com>
Fri, 12 Oct 2018 19:32:33 +0000 (15:32 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 13 Nov 2018 19:15:15 +0000 (11:15 -0800)
commit ad22cf6ea47fa20fbe11ac324a0a15c0a9a4a2a9 upstream.

We can't use entry->bytes if our entry is a bitmap entry, we need to use
entry->max_extent_size in that case.  Fix up all the logic to make this
consistent.

CC: stable@vger.kernel.org # 4.4+
Signed-off-by: Josef Bacik <jbacik@fb.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/btrfs/free-space-cache.c

index 9b3fbe7c16a910d0a06e03ff10fb443dc792a99b..a8b4e4d7b82def81c5b30532a71245926e664fe1 100644 (file)
@@ -1795,6 +1795,13 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl,
        return -1;
 }
 
+static inline u64 get_max_extent_size(struct btrfs_free_space *entry)
+{
+       if (entry->bitmap)
+               return entry->max_extent_size;
+       return entry->bytes;
+}
+
 /* Cache the size of the max extent in bytes */
 static struct btrfs_free_space *
 find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
@@ -1816,8 +1823,8 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
        for (node = &entry->offset_index; node; node = rb_next(node)) {
                entry = rb_entry(node, struct btrfs_free_space, offset_index);
                if (entry->bytes < *bytes) {
-                       if (entry->bytes > *max_extent_size)
-                               *max_extent_size = entry->bytes;
+                       *max_extent_size = max(get_max_extent_size(entry),
+                                              *max_extent_size);
                        continue;
                }
 
@@ -1835,8 +1842,8 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
                }
 
                if (entry->bytes < *bytes + align_off) {
-                       if (entry->bytes > *max_extent_size)
-                               *max_extent_size = entry->bytes;
+                       *max_extent_size = max(get_max_extent_size(entry),
+                                              *max_extent_size);
                        continue;
                }
 
@@ -1848,8 +1855,10 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
                                *offset = tmp;
                                *bytes = size;
                                return entry;
-                       } else if (size > *max_extent_size) {
-                               *max_extent_size = size;
+                       } else {
+                               *max_extent_size =
+                                       max(get_max_extent_size(entry),
+                                           *max_extent_size);
                        }
                        continue;
                }
@@ -2709,8 +2718,8 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,
 
        err = search_bitmap(ctl, entry, &search_start, &search_bytes, true);
        if (err) {
-               if (search_bytes > *max_extent_size)
-                       *max_extent_size = search_bytes;
+               *max_extent_size = max(get_max_extent_size(entry),
+                                      *max_extent_size);
                return 0;
        }
 
@@ -2747,8 +2756,9 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
 
        entry = rb_entry(node, struct btrfs_free_space, offset_index);
        while (1) {
-               if (entry->bytes < bytes && entry->bytes > *max_extent_size)
-                       *max_extent_size = entry->bytes;
+               if (entry->bytes < bytes)
+                       *max_extent_size = max(get_max_extent_size(entry),
+                                              *max_extent_size);
 
                if (entry->bytes < bytes ||
                    (!entry->bitmap && entry->offset < min_start)) {