Commit 0ef3e66b authored by Chris Mason's avatar Chris Mason

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: default avatarChris Mason <chris.mason@oracle.com>
parent 515dc322
...@@ -363,7 +363,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, ...@@ -363,7 +363,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
other = btrfs_node_blockptr(parent, i - 1); other = btrfs_node_blockptr(parent, i - 1);
close = close_blocks(blocknr, other, blocksize); 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); other = btrfs_node_blockptr(parent, i + 1);
close = close_blocks(blocknr, other, blocksize); close = close_blocks(blocknr, other, blocksize);
} }
......
...@@ -464,6 +464,7 @@ struct btrfs_space_info { ...@@ -464,6 +464,7 @@ struct btrfs_space_info {
u64 bytes_used; u64 bytes_used;
u64 bytes_pinned; u64 bytes_pinned;
int full; int full;
int force_alloc;
struct list_head list; struct list_head list;
}; };
...@@ -589,6 +590,7 @@ struct btrfs_root { ...@@ -589,6 +590,7 @@ struct btrfs_root {
int ref_cows; int ref_cows;
int track_dirty; int track_dirty;
struct btrfs_key defrag_progress; struct btrfs_key defrag_progress;
struct btrfs_key defrag_max;
int defrag_running; int defrag_running;
int defrag_level; int defrag_level;
char *name; char *name;
......
This diff is collapsed.
...@@ -198,6 +198,13 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, ...@@ -198,6 +198,13 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
goto out; goto out;
} }
if (root->defrag_progress.objectid == 0) { 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); extent_buffer_get(root->node);
ret = btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp); ret = btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp);
BUG_ON(ret); BUG_ON(ret);
...@@ -254,6 +261,16 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, ...@@ -254,6 +261,16 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
out: out:
if (path) if (path)
btrfs_free_path(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) { if (ret != -EAGAIN) {
memset(&root->defrag_progress, 0, memset(&root->defrag_progress, 0,
sizeof(root->defrag_progress)); sizeof(root->defrag_progress));
......
...@@ -750,10 +750,6 @@ static int btrfs_rm_dev_item(struct btrfs_root *root, ...@@ -750,10 +750,6 @@ static int btrfs_rm_dev_item(struct btrfs_root *root,
if (bdev == fs_devices->latest_bdev) if (bdev == fs_devices->latest_bdev)
fs_devices->latest_bdev = next_dev->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); total_bytes = btrfs_super_num_devices(&root->fs_info->super_copy);
btrfs_set_super_num_devices(&root->fs_info->super_copy, btrfs_set_super_num_devices(&root->fs_info->super_copy,
total_bytes - 1); total_bytes - 1);
...@@ -849,6 +845,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) ...@@ -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->num_devices--;
root->fs_info->fs_devices->open_devices--;
ret = btrfs_shrink_device(device, 0); ret = btrfs_shrink_device(device, 0);
if (ret) if (ret)
...@@ -873,7 +870,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) ...@@ -873,7 +870,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
if (device->bdev) { if (device->bdev) {
/* one close for the device struct or super_block */ /* one close for the device struct or super_block */
close_bdev_excl(device->bdev); close_bdev_excl(device->bdev);
root->fs_info->fs_devices->open_devices--;
} }
if (bdev) { if (bdev) {
/* one close for us */ /* one close for us */
...@@ -1450,7 +1446,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, ...@@ -1450,7 +1446,7 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
return -ENOSPC; return -ENOSPC;
if (type & (BTRFS_BLOCK_GROUP_RAID0)) { 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; min_stripes = 2;
} }
if (type & (BTRFS_BLOCK_GROUP_DUP)) { if (type & (BTRFS_BLOCK_GROUP_DUP)) {
...@@ -1459,13 +1455,13 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, ...@@ -1459,13 +1455,13 @@ int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
} }
if (type & (BTRFS_BLOCK_GROUP_RAID1)) { if (type & (BTRFS_BLOCK_GROUP_RAID1)) {
num_stripes = min_t(u64, 2, 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) if (num_stripes < 2)
return -ENOSPC; return -ENOSPC;
min_stripes = 2; min_stripes = 2;
} }
if (type & (BTRFS_BLOCK_GROUP_RAID10)) { 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) if (num_stripes < 4)
return -ENOSPC; return -ENOSPC;
num_stripes &= ~(u32)1; num_stripes &= ~(u32)1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment