fprintf(stderr, "Could not allocate new cluster: %s\n",
strerror(-new_offset));
ret = new_offset;
- goto fail;
+ goto done;
}
/* fetch current refcount block content */
ret = qcow2_cache_get(bs, s->refcount_block_cache, offset, &refcount_block);
if (ret < 0) {
fprintf(stderr, "Could not fetch refcount block: %s\n", strerror(-ret));
- goto fail;
+ goto fail_free_cluster;
}
/* new block has not yet been entered into refcount table, therefore it is
"check failed: %s\n", strerror(-ret));
/* the image will be marked corrupt, so don't even attempt on freeing
* the cluster */
- new_offset = 0;
- goto fail;
+ goto done;
}
/* write to new block */
s->cluster_sectors);
if (ret < 0) {
fprintf(stderr, "Could not write refcount block: %s\n", strerror(-ret));
- goto fail;
+ goto fail_free_cluster;
}
/* update refcount table */
if (ret < 0) {
fprintf(stderr, "Could not update refcount table: %s\n",
strerror(-ret));
- goto fail;
+ goto fail_free_cluster;
}
-fail:
- if (new_offset && (ret < 0)) {
- qcow2_free_clusters(bs, new_offset, s->cluster_size,
- QCOW2_DISCARD_ALWAYS);
- }
+ goto done;
+
+fail_free_cluster:
+ qcow2_free_clusters(bs, new_offset, s->cluster_size, QCOW2_DISCARD_OTHER);
+
+done:
if (refcount_block) {
- if (ret < 0) {
- qcow2_cache_put(bs, s->refcount_block_cache, &refcount_block);
- } else {
- ret = qcow2_cache_put(bs, s->refcount_block_cache, &refcount_block);
- }
+ /* This should never fail, as it would only do so if the given refcount
+ * block cannot be found in the cache. As this is impossible as long as
+ * there are no bugs, assert the success. */
+ int tmp = qcow2_cache_put(bs, s->refcount_block_cache, &refcount_block);
+ assert(tmp == 0);
}
+
if (ret < 0) {
return ret;
}
+
return new_offset;
}