[sheepdog] [PATCH 2/2] sheep: clear child vdi for deletion of clone
Liu Yuan
namei.unix at gmail.com
Fri Feb 14 07:20:46 CET 2014
This will fix a bug that after deletion of clones, we fail to create clones
with the snapshot that we previousy cloned.
Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
sheep/vdi.c | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/sheep/vdi.c b/sheep/vdi.c
index f4c589a..c627d26 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -1028,6 +1028,48 @@ static uint64_t get_vdi_root(uint32_t vid, bool *cloned)
return vid;
}
+static void clear_parent_child_vdi(uint32_t vid)
+{
+ struct sd_inode * inode = xmalloc(SD_INODE_HEADER_SIZE);
+ uint32_t pvid, i;
+ int ret;
+
+ ret = read_backend_object(vid_to_vdi_oid(vid), (char *)inode,
+ SD_INODE_HEADER_SIZE, 0);
+ if (ret != SD_RES_SUCCESS) {
+ sd_err("failed to read inode %"PRIx32, vid);
+ goto out;
+ }
+
+ pvid = inode->parent_vdi_id;
+ ret = read_backend_object(vid_to_vdi_oid(pvid), (char *)inode,
+ SD_INODE_HEADER_SIZE, 0);
+ if (ret != SD_RES_SUCCESS) {
+ sd_err("failed to read parent inode %"PRIx32, pvid);
+ goto out;
+ }
+
+ for (i = 0; i < MAX_CHILDREN; i++)
+ if (inode->child_vdi_id[i] == vid) {
+ inode->child_vdi_id[i] = 0;
+ break;
+ }
+
+ if (i == MAX_CHILDREN) {
+ sd_info("failed to find child %"PRIx32, vid);
+ goto out;
+ }
+
+ ret = sd_write_object(vid_to_vdi_oid(pvid), (char *)inode,
+ SD_INODE_HEADER_SIZE, 0, false);
+ if (ret != SD_RES_SUCCESS) {
+ sd_err("failed to update parent %"PRIx32, pvid);
+ goto out;
+ }
+out:
+ free(inode);
+}
+
static int start_deletion(struct request *req, uint32_t vid)
{
struct deletion_work *dw = NULL;
@@ -1066,6 +1108,7 @@ static int start_deletion(struct request *req, uint32_t vid)
if (cloned) {
dw->delete_vid_array[0] = vid;
dw->delete_vid_count = 1;
+ clear_parent_child_vdi(vid);
} else {
sd_debug("snapshot chain has valid vdi, just mark vdi %"
PRIx32 " as deleted.", dw->target_vid);
--
1.8.1.2
More information about the sheepdog
mailing list