summaryrefslogtreecommitdiff
path: root/cmds-check.c
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2016-01-06 15:08:46 +0100
committerDavid Sterba <dsterba@suse.com>2016-01-12 15:01:07 +0100
commite0a28fa2fd9fdd570fc0e44e7f6f6743706cdc71 (patch)
tree4c1424f338016ac414decac474887d01c8de1887 /cmds-check.c
parent441f88498dccc734bab3d0091eabdeed2fec1417 (diff)
btrfs-progs: return errors from clone_inode_rec, fail in callers
clone_inode_rec return value is enahanced, callers will just BUG_ON now and will be fixed one by one. Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'cmds-check.c')
-rw-r--r--cmds-check.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/cmds-check.c b/cmds-check.c
index 161dfcb0..77982eeb 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -566,12 +566,15 @@ static struct inode_record *clone_inode_rec(struct inode_record *orig_rec)
struct inode_record *rec;
struct inode_backref *backref;
struct inode_backref *orig;
+ struct inode_backref *tmp;
struct orphan_data_extent *src_orphan;
struct orphan_data_extent *dst_orphan;
size_t size;
int ret;
rec = malloc(sizeof(*rec));
+ if (!rec)
+ return ERR_PTR(-ENOMEM);
memcpy(rec, orig_rec, sizeof(*rec));
rec->refs = 1;
INIT_LIST_HEAD(&rec->backrefs);
@@ -581,13 +584,19 @@ static struct inode_record *clone_inode_rec(struct inode_record *orig_rec)
list_for_each_entry(orig, &orig_rec->backrefs, list) {
size = sizeof(*orig) + orig->namelen + 1;
backref = malloc(size);
+ if (!backref) {
+ ret = -ENOMEM;
+ goto cleanup;
+ }
memcpy(backref, orig, size);
list_add_tail(&backref->list, &rec->backrefs);
}
list_for_each_entry(src_orphan, &orig_rec->orphan_extents, list) {
dst_orphan = malloc(sizeof(*dst_orphan));
- /* TODO: Fix all the HELL of un-catched -ENOMEM case */
- BUG_ON(!dst_orphan);
+ if (!dst_orphan) {
+ ret = -ENOMEM;
+ goto cleanup;
+ }
memcpy(dst_orphan, src_orphan, sizeof(*src_orphan));
list_add_tail(&dst_orphan->list, &rec->orphan_extents);
}
@@ -595,6 +604,23 @@ static struct inode_record *clone_inode_rec(struct inode_record *orig_rec)
BUG_ON(ret < 0);
return rec;
+
+cleanup:
+ if (!list_empty(&rec->backrefs))
+ list_for_each_entry_safe(orig, tmp, &rec->backrefs, list) {
+ list_del(&orig->list);
+ free(orig);
+ }
+
+ if (!list_empty(&rec->orphan_extents))
+ list_for_each_entry_safe(orig, tmp, &rec->orphan_extents, list) {
+ list_del(&orig->list);
+ free(orig);
+ }
+
+ free(rec);
+
+ return ERR_PTR(ret);
}
static void print_orphan_data_extents(struct list_head *orphan_extents,
@@ -730,6 +756,8 @@ static struct inode_record *get_inode_rec(struct cache_tree *inode_cache,
rec = node->data;
if (mod && rec->refs > 1) {
node->data = clone_inode_rec(rec);
+ if (IS_ERR(node->data))
+ return node->data;
rec->refs--;
rec = node->data;
}