mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Btrfs: Allocator fix variety pack
* Force chunk allocation when find_free_extent has to do a full scan * Record the max key at the start of defrag so it doesn't run forever * Block groups might not be contiguous, make a forward search for the next block group in extent-tree.c * Get rid of extra checks for total fs size * Fix relocate_one_reference to avoid relocating the same file data block twice when referenced by an older transaction * Use the open device count when allocating chunks so that we don't try to allocate from devices that don't exist Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
+1
-1
@@ -363,7 +363,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
|
||||
other = btrfs_node_blockptr(parent, i - 1);
|
||||
close = close_blocks(blocknr, other, blocksize);
|
||||
}
|
||||
if (close && i < end_slot - 2) {
|
||||
if (!close && i < end_slot - 2) {
|
||||
other = btrfs_node_blockptr(parent, i + 1);
|
||||
close = close_blocks(blocknr, other, blocksize);
|
||||
}
|
||||
|
||||
@@ -464,6 +464,7 @@ struct btrfs_space_info {
|
||||
u64 bytes_used;
|
||||
u64 bytes_pinned;
|
||||
int full;
|
||||
int force_alloc;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
@@ -589,6 +590,7 @@ struct btrfs_root {
|
||||
int ref_cows;
|
||||
int track_dirty;
|
||||
struct btrfs_key defrag_progress;
|
||||
struct btrfs_key defrag_max;
|
||||
int defrag_running;
|
||||
int defrag_level;
|
||||
char *name;
|
||||
|
||||
+188
-91
File diff suppressed because it is too large
Load Diff
@@ -198,6 +198,13 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
|
||||
goto out;
|
||||
}
|
||||
if (root->defrag_progress.objectid == 0) {
|
||||
u32 nritems;
|
||||
|
||||
nritems = btrfs_header_nritems(root->node);
|
||||
root->defrag_max.objectid = 0;
|
||||
/* from above we know this is not a leaf */
|
||||
btrfs_node_key_to_cpu(root->node, &root->defrag_max,
|
||||
nritems - 1);
|
||||
extent_buffer_get(root->node);
|
||||
ret = btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp);
|
||||
BUG_ON(ret);
|
||||
@@ -254,6 +261,16 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
|
||||
out:
|
||||
if (path)
|
||||
btrfs_free_path(path);
|
||||
if (ret == -EAGAIN) {
|
||||
if (root->defrag_max.objectid > root->defrag_progress.objectid)
|
||||
goto done;
|
||||
if (root->defrag_max.type > root->defrag_progress.type)
|
||||
goto done;
|
||||
if (root->defrag_max.offset > root->defrag_progress.offset)
|
||||
goto done;
|
||||
ret = 0;
|
||||
}
|
||||
done:
|
||||
if (ret != -EAGAIN) {
|
||||
memset(&root->defrag_progress, 0,
|
||||
sizeof(root->defrag_progress));
|
||||
|
||||
+4
-8
@@ -750,10 +750,6 @@ static int btrfs_rm_dev_item(struct btrfs_root *root,
|
||||
if (bdev == fs_devices->latest_bdev)
|
||||
fs_devices->latest_bdev = next_dev->bdev;
|
||||
|
||||
total_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
|
||||
btrfs_set_super_total_bytes(&root->fs_info->super_copy,
|
||||
total_bytes - device->total_bytes);
|
||||
|
||||
total_bytes = btrfs_super_num_devices(&root->fs_info->super_copy);
|
||||
btrfs_set_super_num_devices(&root->fs_info->super_copy,
|
||||
total_bytes - 1);
|
||||
@@ -849,6 +845,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
|
||||
|
||||
}
|
||||
root->fs_info->fs_devices->num_devices--;
|
||||
root->fs_info->fs_devices->open_devices--;
|
||||
|
||||
ret = btrfs_shrink_device(device, 0);
|
||||
if (ret)
|
||||
@@ -873,7 +870,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
|
||||
if (device->bdev) {
|
||||
/* one close for the device struct or super_block */
|
||||
close_bdev_excl(device->bdev);
|
||||
root->fs_info->fs_devices->open_devices--;
|
||||
}
|
||||
if (bdev) {
|
||||
/* one close for us */
|
||||
@@ -1450,7 +1446,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
|
||||
return -ENOSPC;
|
||||
|
||||
if (type & (BTRFS_BLOCK_GROUP_RAID0)) {
|
||||
num_stripes = btrfs_super_num_devices(&info->super_copy);
|
||||
num_stripes = extent_root->fs_info->fs_devices->open_devices;
|
||||
min_stripes = 2;
|
||||
}
|
||||
if (type & (BTRFS_BLOCK_GROUP_DUP)) {
|
||||
@@ -1459,13 +1455,13 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
|
||||
}
|
||||
if (type & (BTRFS_BLOCK_GROUP_RAID1)) {
|
||||
num_stripes = min_t(u64, 2,
|
||||
btrfs_super_num_devices(&info->super_copy));
|
||||
extent_root->fs_info->fs_devices->open_devices);
|
||||
if (num_stripes < 2)
|
||||
return -ENOSPC;
|
||||
min_stripes = 2;
|
||||
}
|
||||
if (type & (BTRFS_BLOCK_GROUP_RAID10)) {
|
||||
num_stripes = btrfs_super_num_devices(&info->super_copy);
|
||||
num_stripes = extent_root->fs_info->fs_devices->open_devices;
|
||||
if (num_stripes < 4)
|
||||
return -ENOSPC;
|
||||
num_stripes &= ~(u32)1;
|
||||
|
||||
Reference in New Issue
Block a user