[sheepdog] [PATCH v5 7/8] copy middle-node when vdi_clone() for hyper volume
Robin Dong
robin.k.dong at gmail.com
Tue Nov 5 10:56:30 CET 2013
Copy all middle-nodes when clone a hyper volume.
Signed-off-by: Robin Dong <sanbai at taobao.com>
---
include/sheepdog_proto.h | 5 ++++-
lib/sd_inode.c | 34 ++++++++++++++++++++++++++++++++--
sheep/vdi.c | 4 +++-
3 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index 87813ac..4623f31 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -284,7 +284,10 @@ extern int sd_inode_write_vid(write_node_fn writer, struct sd_inode *inode,
uint32_t idx, uint32_t vid, uint32_t value,
int flags, bool create, bool direct);
extern uint32_t sd_inode_get_meta_size(struct sd_inode *inode, size_t size);
-extern void sd_inode_copy_vdis(struct sd_inode *oldi, struct sd_inode *newi);
+extern void sd_inode_copy_vdis(write_node_fn writer, read_node_fn reader,
+ uint32_t *data_vdi_id, uint8_t store_policy,
+ uint8_t nr_copies, uint8_t copy_policy,
+ struct sd_inode *newi);
typedef void (*btree_cb_fn)(void *data, enum btree_node_type type, void *arg);
extern void traverse_btree(read_node_fn reader, const struct sd_inode *inode,
diff --git a/lib/sd_inode.c b/lib/sd_inode.c
index 1d23c76..0e9521e 100644
--- a/lib/sd_inode.c
+++ b/lib/sd_inode.c
@@ -648,8 +648,38 @@ int sd_inode_write_vid(write_node_fn writer, struct sd_inode *inode,
return ret;
}
-void sd_inode_copy_vdis(struct sd_inode *oldi, struct sd_inode *newi)
+void sd_inode_copy_vdis(write_node_fn writer, read_node_fn reader,
+ uint32_t *data_vdi_id, uint8_t store_policy,
+ uint8_t nr_copies, uint8_t copy_policy,
+ struct sd_inode *newi)
{
- memcpy(newi->data_vdi_id, oldi->data_vdi_id, sizeof(newi->data_vdi_id));
+ struct sd_extent_header *header = EXT_HEADER(data_vdi_id);
+ struct sd_extent_header *leaf_node;
+ struct sd_extent_idx *last_idx, *old_iter_idx, *new_iter_idx;
+ uint64_t oid;
+ void *tmp;
+
+ memcpy(newi->data_vdi_id, data_vdi_id, sizeof(newi->data_vdi_id));
+
+ if (store_policy == 1 && header->depth > 1) {
+ /* for B-tree (> 1 level), it needs to copy all leaf-node */
+ last_idx = LAST_IDX(data_vdi_id);
+ old_iter_idx = FIRST_IDX(data_vdi_id);
+ new_iter_idx = FIRST_IDX(newi->data_vdi_id);
+ leaf_node = xmalloc(SD_INODE_DATA_INDEX_SIZE);
+ tmp = (void *)leaf_node;
+ while (old_iter_idx != last_idx) {
+ reader(old_iter_idx->oid, &tmp,
+ SD_INODE_DATA_INDEX_SIZE, 0);
+ oid = vid_to_btree_oid(newi->vdi_id,
+ newi->btree_counter++);
+ writer(oid, leaf_node, SD_INODE_DATA_INDEX_SIZE, 0, 0,
+ nr_copies, copy_policy, true, false);
+ new_iter_idx->oid = oid;
+ old_iter_idx++;
+ new_iter_idx++;
+ }
+ free(leaf_node);
+ }
}
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 3d4af76..ada1f83 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -238,7 +238,9 @@ static struct sd_inode *alloc_inode(const struct vdi_iocb *iocb,
new->snap_id = new_snapid;
new->parent_vdi_id = iocb->base_vid;
if (data_vdi_id)
- memcpy(new->data_vdi_id, data_vdi_id, sizeof(new->data_vdi_id));
+ sd_inode_copy_vdis(sheep_bnode_writer, sheep_bnode_reader,
+ data_vdi_id, iocb->store_policy,
+ iocb->nr_copies, iocb->copy_policy, new);
else if (new->store_policy)
sd_inode_init(new->data_vdi_id, 1);
--
1.7.1
More information about the sheepdog
mailing list