add_extent_rec_nolookup(extent_cache, &tmpl);
+ /* really a bug in cache_extent implement now */
cache = lookup_cache_extent(extent_cache, bytenr, 1);
if (!cache)
- abort();
+ return -ENOENT;
}
rec = container_of(cache, struct extent_record, cache);
if (rec->start != bytenr) {
- abort();
+ /*
+ * Several cause, from unaligned bytenr to over lapping extents
+ */
+ return -EEXIST;
}
back = find_tree_backref(rec, parent, root);
if (!back) {
back = alloc_tree_backref(rec, parent, root);
- BUG_ON(!back);
+ if (!back)
+ return -ENOMEM;
}
if (found_ref) {
{
struct btrfs_extent_ref_v0 *ref0;
struct btrfs_key key;
+ int ret;
btrfs_item_key_to_cpu(leaf, &key, slot);
ref0 = btrfs_item_ptr(leaf, slot, struct btrfs_extent_ref_v0);
if (btrfs_ref_objectid_v0(leaf, ref0) < BTRFS_FIRST_FREE_OBJECTID) {
- add_tree_backref(extent_cache, key.objectid, key.offset, 0, 0);
+ ret = add_tree_backref(extent_cache, key.objectid, key.offset,
+ 0, 0);
} else {
- add_data_backref(extent_cache, key.objectid, key.offset, 0,
- 0, 0, btrfs_ref_count_v0(leaf, ref0), 0, 0);
+ ret = add_data_backref(extent_cache, key.objectid, key.offset,
+ 0, 0, 0, btrfs_ref_count_v0(leaf, ref0), 0, 0);
}
- return 0;
+ return ret;
}
#endif
struct extent_record tmpl;
unsigned long end;
unsigned long ptr;
+ int ret;
int type;
u32 item_size = btrfs_item_size_nr(eb, slot);
u64 refs = 0;
offset = btrfs_extent_inline_ref_offset(eb, iref);
switch (type) {
case BTRFS_TREE_BLOCK_REF_KEY:
- add_tree_backref(extent_cache, key.objectid,
- 0, offset, 0);
+ ret = add_tree_backref(extent_cache, key.objectid,
+ 0, offset, 0);
+ if (ret < 0)
+ error("add_tree_backref failed: %s",
+ strerror(-ret));
break;
case BTRFS_SHARED_BLOCK_REF_KEY:
- add_tree_backref(extent_cache, key.objectid,
- offset, 0, 0);
+ ret = add_tree_backref(extent_cache, key.objectid,
+ offset, 0, 0);
+ if (ret < 0)
+ error("add_tree_backref failed: %s",
+ strerror(-ret));
break;
case BTRFS_EXTENT_DATA_REF_KEY:
dref = (struct btrfs_extent_data_ref *)(&iref->offset);
}
if (key.type == BTRFS_TREE_BLOCK_REF_KEY) {
- add_tree_backref(extent_cache, key.objectid, 0,
- key.offset, 0);
+ ret = add_tree_backref(extent_cache,
+ key.objectid, 0, key.offset, 0);
+ if (ret < 0)
+ error("add_tree_backref failed: %s",
+ strerror(-ret));
continue;
}
if (key.type == BTRFS_SHARED_BLOCK_REF_KEY) {
- add_tree_backref(extent_cache, key.objectid,
- key.offset, 0, 0);
+ ret = add_tree_backref(extent_cache,
+ key.objectid, key.offset, 0, 0);
+ if (ret < 0)
+ error("add_tree_backref failed: %s",
+ strerror(-ret));
continue;
}
if (key.type == BTRFS_EXTENT_DATA_REF_KEY) {
tmpl.metadata = 1;
tmpl.max_size = size;
ret = add_extent_rec(extent_cache, &tmpl);
- BUG_ON(ret);
+ if (ret < 0)
+ goto out;
- add_tree_backref(extent_cache, ptr, parent, owner, 1);
+ ret = add_tree_backref(extent_cache, ptr, parent,
+ owner, 1);
+ if (ret < 0) {
+ error("add_tree_backref failed: %s",
+ strerror(-ret));
+ continue;
+ }
if (level > 1) {
add_pending(nodes, seen, ptr, size);
u64 objectid)
{
struct extent_record tmpl;
+ int ret;
if (btrfs_header_level(buf) > 0)
add_pending(nodes, seen, buf->start, buf->len);
if (objectid == BTRFS_TREE_RELOC_OBJECTID ||
btrfs_header_backref_rev(buf) < BTRFS_MIXED_BACKREF_REV)
- add_tree_backref(extent_cache, buf->start, buf->start,
- 0, 1);
+ ret = add_tree_backref(extent_cache, buf->start, buf->start,
+ 0, 1);
else
- add_tree_backref(extent_cache, buf->start, 0, objectid, 1);
- return 0;
+ ret = add_tree_backref(extent_cache, buf->start, 0, objectid,
+ 1);
+ return ret;
}
/* as we fix the tree, we might be deleting blocks that
ret = -EIO;
break;
}
- add_root_to_pending(buf, extent_cache, pending,
+ ret = add_root_to_pending(buf, extent_cache, pending,
seen, nodes, rec->objectid);
+ if (ret < 0)
+ break;
/*
* To rebuild extent tree, we need deal with snapshot
* one by one, otherwise we deal with node firstly which