Commit b1c79e09 authored by Josef Bacik's avatar Josef Bacik

Btrfs: handle running extent ops with skinny metadata

Chris hit a bug where we weren't finding extent records when running extent ops.
This is because we use the delayed_ref_head when running the extent op, which
means we can't use the ->type checks to see if we are metadata.  We also lose
the level of the metadata we are working on.  So to fix this we can just check
the ->is_data section of the extent_op, and we can store the level of the buffer
we were modifying in the extent_op.  Thanks,
Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
parent 73e1e61f
...@@ -951,10 +951,12 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, ...@@ -951,10 +951,12 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
BUG_ON(ret); /* -ENOMEM */ BUG_ON(ret); /* -ENOMEM */
} }
if (new_flags != 0) { if (new_flags != 0) {
int level = btrfs_header_level(buf);
ret = btrfs_set_disk_extent_flags(trans, root, ret = btrfs_set_disk_extent_flags(trans, root,
buf->start, buf->start,
buf->len, buf->len,
new_flags, 0); new_flags, level, 0);
if (ret) if (ret)
return ret; return ret;
} }
......
...@@ -3075,7 +3075,7 @@ int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, ...@@ -3075,7 +3075,7 @@ int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
u64 bytenr, u64 num_bytes, u64 flags, u64 bytenr, u64 num_bytes, u64 flags,
int is_data); int level, int is_data);
int btrfs_free_extent(struct btrfs_trans_handle *trans, int btrfs_free_extent(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid,
......
...@@ -60,6 +60,7 @@ struct btrfs_delayed_ref_node { ...@@ -60,6 +60,7 @@ struct btrfs_delayed_ref_node {
struct btrfs_delayed_extent_op { struct btrfs_delayed_extent_op {
struct btrfs_disk_key key; struct btrfs_disk_key key;
u64 flags_to_set; u64 flags_to_set;
int level;
unsigned int update_key:1; unsigned int update_key:1;
unsigned int update_flags:1; unsigned int update_flags:1;
unsigned int is_data:1; unsigned int is_data:1;
......
...@@ -2070,8 +2070,7 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans, ...@@ -2070,8 +2070,7 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans,
u32 item_size; u32 item_size;
int ret; int ret;
int err = 0; int err = 0;
int metadata = (node->type == BTRFS_TREE_BLOCK_REF_KEY || int metadata = !extent_op->is_data;
node->type == BTRFS_SHARED_BLOCK_REF_KEY);
if (trans->aborted) if (trans->aborted)
return 0; return 0;
...@@ -2086,11 +2085,8 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans, ...@@ -2086,11 +2085,8 @@ static int run_delayed_extent_op(struct btrfs_trans_handle *trans,
key.objectid = node->bytenr; key.objectid = node->bytenr;
if (metadata) { if (metadata) {
struct btrfs_delayed_tree_ref *tree_ref;
tree_ref = btrfs_delayed_node_to_tree_ref(node);
key.type = BTRFS_METADATA_ITEM_KEY; key.type = BTRFS_METADATA_ITEM_KEY;
key.offset = tree_ref->level; key.offset = extent_op->level;
} else { } else {
key.type = BTRFS_EXTENT_ITEM_KEY; key.type = BTRFS_EXTENT_ITEM_KEY;
key.offset = node->num_bytes; key.offset = node->num_bytes;
...@@ -2719,7 +2715,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, ...@@ -2719,7 +2715,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_root *root,
u64 bytenr, u64 num_bytes, u64 flags, u64 bytenr, u64 num_bytes, u64 flags,
int is_data) int level, int is_data)
{ {
struct btrfs_delayed_extent_op *extent_op; struct btrfs_delayed_extent_op *extent_op;
int ret; int ret;
...@@ -2732,6 +2728,7 @@ int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, ...@@ -2732,6 +2728,7 @@ int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans,
extent_op->update_flags = 1; extent_op->update_flags = 1;
extent_op->update_key = 0; extent_op->update_key = 0;
extent_op->is_data = is_data ? 1 : 0; extent_op->is_data = is_data ? 1 : 0;
extent_op->level = level;
ret = btrfs_add_delayed_extent_op(root->fs_info, trans, bytenr, ret = btrfs_add_delayed_extent_op(root->fs_info, trans, bytenr,
num_bytes, extent_op); num_bytes, extent_op);
...@@ -6763,6 +6760,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, ...@@ -6763,6 +6760,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans,
extent_op->update_key = 1; extent_op->update_key = 1;
extent_op->update_flags = 1; extent_op->update_flags = 1;
extent_op->is_data = 0; extent_op->is_data = 0;
extent_op->level = level;
ret = btrfs_add_delayed_tree_ref(root->fs_info, trans, ret = btrfs_add_delayed_tree_ref(root->fs_info, trans,
ins.objectid, ins.objectid,
...@@ -6934,7 +6932,8 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, ...@@ -6934,7 +6932,8 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans,
ret = btrfs_dec_ref(trans, root, eb, 0, wc->for_reloc); ret = btrfs_dec_ref(trans, root, eb, 0, wc->for_reloc);
BUG_ON(ret); /* -ENOMEM */ BUG_ON(ret); /* -ENOMEM */
ret = btrfs_set_disk_extent_flags(trans, root, eb->start, ret = btrfs_set_disk_extent_flags(trans, root, eb->start,
eb->len, flag, 0); eb->len, flag,
btrfs_header_level(eb), 0);
BUG_ON(ret); /* -ENOMEM */ BUG_ON(ret); /* -ENOMEM */
wc->flags[level] |= flag; wc->flags[level] |= flag;
} }
......
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