Commit 081e9573 authored by Chris Mason's avatar Chris Mason

Btrfs: Make defrag check nodes against the progress key to prevent repeating work

Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent c549228f
...@@ -161,6 +161,31 @@ static int close_blocks(u64 blocknr, u64 other, u32 blocksize) ...@@ -161,6 +161,31 @@ static int close_blocks(u64 blocknr, u64 other, u32 blocksize)
return 0; return 0;
} }
/*
* compare two keys in a memcmp fashion
*/
static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
{
struct btrfs_key k1;
btrfs_disk_key_to_cpu(&k1, disk);
if (k1.objectid > k2->objectid)
return 1;
if (k1.objectid < k2->objectid)
return -1;
if (k1.type > k2->type)
return 1;
if (k1.type < k2->type)
return -1;
if (k1.offset > k2->offset)
return 1;
if (k1.offset < k2->offset)
return -1;
return 0;
}
int btrfs_realloc_node(struct btrfs_trans_handle *trans, int btrfs_realloc_node(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct extent_buffer *parent, struct btrfs_root *root, struct extent_buffer *parent,
int start_slot, int cache_only, u64 *last_ret, int start_slot, int cache_only, u64 *last_ret,
...@@ -179,6 +204,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, ...@@ -179,6 +204,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
int parent_level; int parent_level;
int uptodate; int uptodate;
u32 blocksize; u32 blocksize;
int progress_passed = 0;
struct btrfs_disk_key disk_key;
parent_level = btrfs_header_level(parent); parent_level = btrfs_header_level(parent);
if (cache_only && parent_level != 1) if (cache_only && parent_level != 1)
...@@ -213,6 +240,11 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans, ...@@ -213,6 +240,11 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
&parent->map_start, &parent->map_len, &parent->map_start, &parent->map_len,
KM_USER1); KM_USER1);
} }
btrfs_node_key(parent, &disk_key, i);
if (!progress_passed && comp_keys(&disk_key, progress) < 0)
continue;
progress_passed = 1;
blocknr = btrfs_node_blockptr(parent, i); blocknr = btrfs_node_blockptr(parent, i);
if (last_block == 0) if (last_block == 0)
last_block = blocknr; last_block = blocknr;
...@@ -292,30 +324,6 @@ static inline unsigned int leaf_data_end(struct btrfs_root *root, ...@@ -292,30 +324,6 @@ static inline unsigned int leaf_data_end(struct btrfs_root *root,
return btrfs_item_offset_nr(leaf, nr - 1); return btrfs_item_offset_nr(leaf, nr - 1);
} }
/*
* compare two keys in a memcmp fashion
*/
static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
{
struct btrfs_key k1;
btrfs_disk_key_to_cpu(&k1, disk);
if (k1.objectid > k2->objectid)
return 1;
if (k1.objectid < k2->objectid)
return -1;
if (k1.type > k2->type)
return 1;
if (k1.type < k2->type)
return -1;
if (k1.offset > k2->offset)
return 1;
if (k1.offset < k2->offset)
return -1;
return 0;
}
static int check_node(struct btrfs_root *root, struct btrfs_path *path, static int check_node(struct btrfs_root *root, struct btrfs_path *path,
int level) int level)
{ {
......
...@@ -227,7 +227,8 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans, ...@@ -227,7 +227,8 @@ int btrfs_defrag_leaves(struct btrfs_trans_handle *trans,
break; break;
if (wret < 0) if (wret < 0)
ret = wret; ret = wret;
ret = -EAGAIN; else
ret = -EAGAIN;
break; break;
} }
for (i = 0; i <= orig_level; i++) { for (i = 0; i <= orig_level; i++) {
......
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