Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason: "These are mostly bug fixes and a two small performance fixes. The most important of the bunch are Josef's fix for a snapshotting regression and Mark's update to fix compile problems on arm" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (25 commits) Btrfs: create the uuid tree on remount rw btrfs: change extent-same to copy entire argument struct Btrfs: dir_inode_operations should use btrfs_update_time also btrfs: Add btrfs: prefix to kernel log output btrfs: refuse to remount read-write after abort Btrfs: btrfs_ioctl_default_subvol: Revert back to toplevel subvolume when arg is 0 Btrfs: don't leak transaction in btrfs_sync_file() Btrfs: add the missing mutex unlock in write_all_supers() Btrfs: iput inode on allocation failure Btrfs: remove space_info->reservation_progress Btrfs: kill delay_iput arg to the wait_ordered functions Btrfs: fix worst case calculator for space usage Revert "Btrfs: rework the overcommit logic to be based on the total size" Btrfs: improve replacing nocow extents Btrfs: drop dir i_size when adding new names on replay Btrfs: replay dir_index items before other items Btrfs: check roots last log commit when checking if an inode has been logged Btrfs: actually log directory we are fsync()'ing Btrfs: actually limit the size of delalloc range Btrfs: allocate the free space by the existed max extent size when ENOSPC ...
This commit is contained in:
@@ -1431,13 +1431,19 @@ static void bitmap_set_bits(struct btrfs_free_space_ctl *ctl,
|
||||
ctl->free_space += bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we can not find suitable extent, we will use bytes to record
|
||||
* the size of the max extent.
|
||||
*/
|
||||
static int search_bitmap(struct btrfs_free_space_ctl *ctl,
|
||||
struct btrfs_free_space *bitmap_info, u64 *offset,
|
||||
u64 *bytes)
|
||||
{
|
||||
unsigned long found_bits = 0;
|
||||
unsigned long max_bits = 0;
|
||||
unsigned long bits, i;
|
||||
unsigned long next_zero;
|
||||
unsigned long extent_bits;
|
||||
|
||||
i = offset_to_bit(bitmap_info->offset, ctl->unit,
|
||||
max_t(u64, *offset, bitmap_info->offset));
|
||||
@@ -1446,9 +1452,12 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl,
|
||||
for_each_set_bit_from(i, bitmap_info->bitmap, BITS_PER_BITMAP) {
|
||||
next_zero = find_next_zero_bit(bitmap_info->bitmap,
|
||||
BITS_PER_BITMAP, i);
|
||||
if ((next_zero - i) >= bits) {
|
||||
found_bits = next_zero - i;
|
||||
extent_bits = next_zero - i;
|
||||
if (extent_bits >= bits) {
|
||||
found_bits = extent_bits;
|
||||
break;
|
||||
} else if (extent_bits > max_bits) {
|
||||
max_bits = extent_bits;
|
||||
}
|
||||
i = next_zero;
|
||||
}
|
||||
@@ -1459,38 +1468,41 @@ static int search_bitmap(struct btrfs_free_space_ctl *ctl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
*bytes = (u64)(max_bits) * ctl->unit;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
unsigned long align)
|
||||
unsigned long align, u64 *max_extent_size)
|
||||
{
|
||||
struct btrfs_free_space *entry;
|
||||
struct rb_node *node;
|
||||
u64 ctl_off;
|
||||
u64 tmp;
|
||||
u64 align_off;
|
||||
int ret;
|
||||
|
||||
if (!ctl->free_space_offset.rb_node)
|
||||
return NULL;
|
||||
goto out;
|
||||
|
||||
entry = tree_search_offset(ctl, offset_to_bitmap(ctl, *offset), 0, 1);
|
||||
if (!entry)
|
||||
return NULL;
|
||||
goto out;
|
||||
|
||||
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 < *bytes) {
|
||||
if (entry->bytes > *max_extent_size)
|
||||
*max_extent_size = entry->bytes;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* make sure the space returned is big enough
|
||||
* to match our requested alignment
|
||||
*/
|
||||
if (*bytes >= align) {
|
||||
ctl_off = entry->offset - ctl->start;
|
||||
tmp = ctl_off + align - 1;;
|
||||
tmp = entry->offset - ctl->start + align - 1;
|
||||
do_div(tmp, align);
|
||||
tmp = tmp * align + ctl->start;
|
||||
align_off = tmp - entry->offset;
|
||||
@@ -1499,14 +1511,22 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
|
||||
tmp = entry->offset;
|
||||
}
|
||||
|
||||
if (entry->bytes < *bytes + align_off)
|
||||
if (entry->bytes < *bytes + align_off) {
|
||||
if (entry->bytes > *max_extent_size)
|
||||
*max_extent_size = entry->bytes;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry->bitmap) {
|
||||
ret = search_bitmap(ctl, entry, &tmp, bytes);
|
||||
u64 size = *bytes;
|
||||
|
||||
ret = search_bitmap(ctl, entry, &tmp, &size);
|
||||
if (!ret) {
|
||||
*offset = tmp;
|
||||
*bytes = size;
|
||||
return entry;
|
||||
} else if (size > *max_extent_size) {
|
||||
*max_extent_size = size;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -1515,7 +1535,7 @@ find_free_space(struct btrfs_free_space_ctl *ctl, u64 *offset, u64 *bytes,
|
||||
*bytes = entry->bytes - align_off;
|
||||
return entry;
|
||||
}
|
||||
|
||||
out:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2116,7 +2136,8 @@ void btrfs_remove_free_space_cache(struct btrfs_block_group_cache *block_group)
|
||||
}
|
||||
|
||||
u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group,
|
||||
u64 offset, u64 bytes, u64 empty_size)
|
||||
u64 offset, u64 bytes, u64 empty_size,
|
||||
u64 *max_extent_size)
|
||||
{
|
||||
struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
|
||||
struct btrfs_free_space *entry = NULL;
|
||||
@@ -2127,7 +2148,7 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group,
|
||||
|
||||
spin_lock(&ctl->tree_lock);
|
||||
entry = find_free_space(ctl, &offset, &bytes_search,
|
||||
block_group->full_stripe_len);
|
||||
block_group->full_stripe_len, max_extent_size);
|
||||
if (!entry)
|
||||
goto out;
|
||||
|
||||
@@ -2137,7 +2158,6 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group,
|
||||
if (!entry->bytes)
|
||||
free_bitmap(ctl, entry);
|
||||
} else {
|
||||
|
||||
unlink_free_space(ctl, entry);
|
||||
align_gap_len = offset - entry->offset;
|
||||
align_gap = entry->offset;
|
||||
@@ -2151,7 +2171,6 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group,
|
||||
else
|
||||
link_free_space(ctl, entry);
|
||||
}
|
||||
|
||||
out:
|
||||
spin_unlock(&ctl->tree_lock);
|
||||
|
||||
@@ -2206,7 +2225,8 @@ int btrfs_return_cluster_to_free_space(
|
||||
static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,
|
||||
struct btrfs_free_cluster *cluster,
|
||||
struct btrfs_free_space *entry,
|
||||
u64 bytes, u64 min_start)
|
||||
u64 bytes, u64 min_start,
|
||||
u64 *max_extent_size)
|
||||
{
|
||||
struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
|
||||
int err;
|
||||
@@ -2218,8 +2238,11 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,
|
||||
search_bytes = bytes;
|
||||
|
||||
err = search_bitmap(ctl, entry, &search_start, &search_bytes);
|
||||
if (err)
|
||||
if (err) {
|
||||
if (search_bytes > *max_extent_size)
|
||||
*max_extent_size = search_bytes;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = search_start;
|
||||
__bitmap_clear_bits(ctl, entry, ret, bytes);
|
||||
@@ -2234,7 +2257,7 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,
|
||||
*/
|
||||
u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
|
||||
struct btrfs_free_cluster *cluster, u64 bytes,
|
||||
u64 min_start)
|
||||
u64 min_start, u64 *max_extent_size)
|
||||
{
|
||||
struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
|
||||
struct btrfs_free_space *entry = NULL;
|
||||
@@ -2254,6 +2277,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 ||
|
||||
(!entry->bitmap && entry->offset < min_start)) {
|
||||
node = rb_next(&entry->offset_index);
|
||||
@@ -2267,7 +2293,8 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
|
||||
if (entry->bitmap) {
|
||||
ret = btrfs_alloc_from_bitmap(block_group,
|
||||
cluster, entry, bytes,
|
||||
cluster->window_start);
|
||||
cluster->window_start,
|
||||
max_extent_size);
|
||||
if (ret == 0) {
|
||||
node = rb_next(&entry->offset_index);
|
||||
if (!node)
|
||||
|
Reference in New Issue
Block a user