Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 65d41e98 authored by Josef Bacik's avatar Josef Bacik Committed by Greg Kroah-Hartman
Browse files

btrfs: set max_extent_size properly



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: default avatarJosef Bacik <jbacik@fb.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 947a9b02
Loading
Loading
Loading
Loading
+20 −10
Original line number Diff line number Diff line
@@ -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)) {