[sheepdog] [PATCH v8 04/10] sheep: extend MAX number of objects

Robin Dong robin.k.dong at gmail.com
Wed Nov 20 07:04:41 CET 2013


Add the max number of objects and add new MACRO for index of inode.
Add store_policy into 'struct vdi_iocq' and 'struct sd_req'

Signed-off-by: Robin Dong <sanbai at taobao.com>
---
 dog/common.c             |    4 ++-
 dog/dog.h                |    2 +-
 dog/farm/farm.c          |   12 ++++++++--
 dog/vdi.c                |   50 ++++++++++++++++++++++++++++++++++-----------
 include/sheepdog_proto.h |   15 +++++++++----
 lib/option.c             |    7 ++++-
 lib/sd_inode.c           |   48 +++++++++++++++++++++++---------------------
 sheep/ops.c              |    1 +
 sheep/sheep_priv.h       |    1 +
 sheep/vdi.c              |    9 +++++--
 10 files changed, 99 insertions(+), 50 deletions(-)

diff --git a/dog/common.c b/dog/common.c
index ee30e81..8dbba8f 100644
--- a/dog/common.c
+++ b/dog/common.c
@@ -155,7 +155,9 @@ int parse_vdi(vdi_parser_func_t func, size_t size, void *data)
 
 		oid = vid_to_vdi_oid(nr);
 
-		ret = sd_read_object(oid, &i, SD_INODE_HEADER_SIZE, 0, true);
+		/* for B-tree inode, we also need sd_extent_header */
+		ret = sd_read_object(oid, &i, SD_INODE_HEADER_SIZE +
+				     sizeof(struct sd_extent_header), 0, true);
 		if (ret != SD_RES_SUCCESS) {
 			sd_err("Failed to read inode header");
 			continue;
diff --git a/dog/dog.h b/dog/dog.h
index 16cafbd..af3cefa 100644
--- a/dog/dog.h
+++ b/dog/dog.h
@@ -84,7 +84,7 @@ void confirm(const char *message);
 void work_queue_wait(struct work_queue *q);
 int do_vdi_create(const char *vdiname, int64_t vdi_size,
 		  uint32_t base_vid, uint32_t *vdi_id, bool snapshot,
-		  uint8_t nr_copies, uint8_t copy_policy);
+		  uint8_t nr_copies, uint8_t copy_policy, uint8_t store_policy);
 int do_vdi_check(const struct sd_inode *inode);
 void show_progress(uint64_t done, uint64_t total, bool raw);
 size_t get_store_objsize(uint8_t copy_policy, uint64_t oid);
diff --git a/dog/farm/farm.c b/dog/farm/farm.c
index 990d26b..3886445 100644
--- a/dog/farm/farm.c
+++ b/dog/farm/farm.c
@@ -29,6 +29,7 @@ struct vdi_entry {
 	uint32_t snap_id;
 	uint8_t  nr_copies;
 	uint8_t copy_policy;
+	uint8_t store_policy;
 	struct rb_node rb;
 };
 static struct rb_root last_vdi_tree = RB_ROOT;
@@ -57,7 +58,8 @@ static struct vdi_entry *find_vdi(const char *name)
 
 static struct vdi_entry *new_vdi(const char *name, uint64_t vdi_size,
 				 uint32_t vdi_id, uint32_t snap_id,
-				 uint8_t nr_copies, uint8_t copy_policy)
+				 uint8_t nr_copies, uint8_t copy_policy,
+				 uint8_t store_policy)
 {
 	struct vdi_entry *vdi;
 	vdi = xmalloc(sizeof(struct vdi_entry));
@@ -67,6 +69,7 @@ static struct vdi_entry *new_vdi(const char *name, uint64_t vdi_size,
 	vdi->snap_id = snap_id;
 	vdi->nr_copies = nr_copies;
 	vdi->copy_policy = copy_policy;
+	vdi->store_policy = store_policy;
 	return vdi;
 }
 
@@ -80,7 +83,8 @@ static void insert_vdi(struct sd_inode *new)
 			      new->vdi_id,
 			      new->snap_id,
 			      new->nr_copies,
-			      new->copy_policy);
+			      new->copy_policy,
+			      new->store_policy);
 		rb_insert(&last_vdi_tree, vdi, rb, vdi_cmp);
 	} else if (vdi->snap_id < new->snap_id) {
 		vdi->vdi_size = new->vdi_size;
@@ -88,6 +92,7 @@ static void insert_vdi(struct sd_inode *new)
 		vdi->snap_id = new->snap_id;
 		vdi->nr_copies = new->nr_copies;
 		vdi->copy_policy = new->copy_policy;
+		vdi->store_policy = new->store_policy;
 	}
 }
 
@@ -100,7 +105,8 @@ static int create_active_vdis(void)
 				  vdi->vdi_size,
 				  vdi->vdi_id, &new_vid,
 				  false, vdi->nr_copies,
-				  vdi->copy_policy) < 0)
+				  vdi->copy_policy,
+				  vdi->store_policy) < 0)
 			return -1;
 	}
 	return 0;
diff --git a/dog/vdi.c b/dog/vdi.c
index b130f3a..69c995c 100644
--- a/dog/vdi.c
+++ b/dog/vdi.c
@@ -31,6 +31,7 @@ static struct sd_option vdi_options[] = {
 	{'c', "copies", true, "specify the data redundancy level"},
 	{'F', "from", true, "create a differential backup from the snapshot"},
 	{'f', "force", false, "do operation forcibly"},
+	{'y', "hyper", false, "create a hyper volume"},
 	{ 0, NULL, false, NULL },
 };
 
@@ -47,6 +48,7 @@ static struct vdi_cmd_data {
 	char from_snapshot_tag[SD_MAX_VDI_TAG_LEN];
 	bool force;
 	uint8_t copy_policy;
+	uint8_t store_policy;
 } vdi_cmd_data = { ~0, };
 
 struct get_vdi_info {
@@ -494,7 +496,7 @@ static int read_vdi_obj(const char *vdiname, int snapid, const char *tag,
 
 int do_vdi_create(const char *vdiname, int64_t vdi_size,
 		  uint32_t base_vid, uint32_t *vdi_id, bool snapshot,
-		  uint8_t nr_copies, uint8_t copy_policy)
+		  uint8_t nr_copies, uint8_t copy_policy, uint8_t store_policy)
 {
 	struct sd_req hdr;
 	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
@@ -513,6 +515,7 @@ int do_vdi_create(const char *vdiname, int64_t vdi_size,
 	hdr.vdi.vdi_size = vdi_size;
 	hdr.vdi.copies = nr_copies;
 	hdr.vdi.copy_policy = copy_policy;
+	hdr.vdi.store_policy = store_policy;
 
 	ret = dog_exec_req(&sd_nid, &hdr, buf);
 	if (ret < 0)
@@ -546,6 +549,15 @@ static int vdi_create(int argc, char **argv)
 	ret = option_parse_size(argv[optind], &size);
 	if (ret < 0)
 		return EXIT_USAGE;
+
+	if (size > SD_OLD_MAX_VDI_SIZE && 0 == vdi_cmd_data.store_policy) {
+		sd_err("VDI size is larger than %s bytes, please use '-y' to "
+		       "create a hyper volume with size up to %s bytes",
+		       strnumber(SD_OLD_MAX_VDI_SIZE),
+		       strnumber(SD_MAX_VDI_SIZE));
+		return EXIT_USAGE;
+	}
+
 	if (size > SD_MAX_VDI_SIZE) {
 		sd_err("VDI size is too large");
 		return EXIT_USAGE;
@@ -558,7 +570,8 @@ static int vdi_create(int argc, char **argv)
 	}
 
 	ret = do_vdi_create(vdiname, size, 0, &vid, false,
-			    vdi_cmd_data.nr_copies, vdi_cmd_data.copy_policy);
+			    vdi_cmd_data.nr_copies, vdi_cmd_data.copy_policy,
+			    vdi_cmd_data.store_policy);
 	if (ret != EXIT_SUCCESS || !vdi_cmd_data.prealloc)
 		goto out;
 
@@ -633,7 +646,8 @@ static int vdi_snapshot(int argc, char **argv)
 		return EXIT_FAILURE;
 
 	ret = do_vdi_create(vdiname, inode->vdi_size, vid, NULL, true,
-			    inode->nr_copies, inode->copy_policy);
+			    inode->nr_copies, inode->copy_policy,
+			    inode->store_policy);
 
 	if (ret == EXIT_SUCCESS && verbose) {
 		if (raw_output)
@@ -677,7 +691,8 @@ static int vdi_clone(int argc, char **argv)
 		goto out;
 
 	ret = do_vdi_create(dst_vdi, inode->vdi_size, base_vid, &new_vid, false,
-			    vdi_cmd_data.nr_copies, inode->copy_policy);
+			    vdi_cmd_data.nr_copies, inode->copy_policy,
+			    inode->store_policy);
 	if (ret != EXIT_SUCCESS || !vdi_cmd_data.prealloc)
 		goto out;
 
@@ -755,15 +770,21 @@ static int vdi_resize(int argc, char **argv)
 	ret = option_parse_size(argv[optind], &new_size);
 	if (ret < 0)
 		return EXIT_USAGE;
-	if (new_size > SD_MAX_VDI_SIZE) {
-		sd_err("New VDI size is too large");
-		return EXIT_USAGE;
-	}
 
 	ret = read_vdi_obj(vdiname, 0, "", &vid, inode, SD_INODE_HEADER_SIZE);
 	if (ret != EXIT_SUCCESS)
 		return ret;
 
+	if (new_size > SD_OLD_MAX_VDI_SIZE && 0 == inode->store_policy) {
+		sd_err("New VDI size is too large");
+		return EXIT_USAGE;
+	}
+
+	if (new_size > SD_MAX_VDI_SIZE) {
+		sd_err("New VDI size is too large");
+		return EXIT_USAGE;
+	}
+
 	if (new_size < inode->vdi_size) {
 		sd_err("Shrinking VDIs is not implemented");
 		return EXIT_USAGE;
@@ -868,7 +889,8 @@ static int vdi_rollback(int argc, char **argv)
 	}
 
 	ret = do_vdi_create(vdiname, inode->vdi_size, base_vid, &new_vid,
-			     false, vdi_cmd_data.nr_copies, inode->copy_policy);
+			     false, vdi_cmd_data.nr_copies, inode->copy_policy,
+			     inode->store_policy);
 
 	if (ret == EXIT_SUCCESS && verbose) {
 		if (raw_output)
@@ -2022,7 +2044,8 @@ static uint32_t do_restore(const char *vdiname, int snapid, const char *tag)
 		goto out;
 
 	ret = do_vdi_create(vdiname, inode->vdi_size, inode->vdi_id, &vid,
-			    false, inode->nr_copies, inode->copy_policy);
+			    false, inode->nr_copies, inode->copy_policy,
+			    inode->store_policy);
 	if (ret != EXIT_SUCCESS) {
 		sd_err("Failed to read VDI");
 		goto out;
@@ -2130,7 +2153,8 @@ out:
 		recovery_ret = do_vdi_create(vdiname, current_inode->vdi_size,
 					     current_inode->parent_vdi_id, NULL,
 					     true, current_inode->nr_copies,
-					     current_inode->copy_policy);
+					     current_inode->copy_policy,
+					     current_inode->store_policy);
 		if (recovery_ret != EXIT_SUCCESS) {
 			sd_err("failed to resume the current vdi");
 			ret = recovery_ret;
@@ -2308,7 +2332,7 @@ static struct subcommand vdi_cmd[] = {
 	{"check", "<vdiname>", "saph", "check and repair image's consistency",
 	 NULL, CMD_NEED_NODELIST|CMD_NEED_ARG,
 	 vdi_check, vdi_options},
-	{"create", "<vdiname> <size>", "Pcaphrv", "create an image",
+	{"create", "<vdiname> <size>", "Pycaphrv", "create an image",
 	 NULL, CMD_NEED_NODELIST|CMD_NEED_ARG,
 	 vdi_create, vdi_options},
 	{"snapshot", "<vdiname>", "saphrv", "create a snapshot",
@@ -2423,6 +2447,8 @@ static int vdi_parser(int ch, const char *opt)
 	case 'f':
 		vdi_cmd_data.force = true;
 		break;
+	case 'y':
+		vdi_cmd_data.store_policy = 1;
 	}
 
 	return 0;
diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index b05d30e..5b2bfa8 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -83,8 +83,7 @@
 /*
  * Object ID rules
  *
- *  0 - 19 (20 bits): data object space
- * 20 - 31 (12 bits): reserved data object space
+ *  0 - 31 (32 bits): data object space
  * 32 - 55 (24 bits): VDI object space
  * 56 - 59 ( 4 bits): reserved VDI object space
  * 60 - 63 ( 4 bits): object type indentifier space
@@ -96,7 +95,8 @@
 #define VMSTATE_BIT (UINT64_C(1) << 62)
 #define VDI_ATTR_BIT (UINT64_C(1) << 61)
 #define VDI_BTREE_BIT (UINT64_C(1) << 60)
-#define MAX_DATA_OBJS (1ULL << 20)
+#define OLD_MAX_DATA_OBJS (1ULL << 20)
+#define MAX_DATA_OBJS (1ULL << 32)
 #define MAX_CHILDREN 1024U
 #define SD_MAX_VDI_LEN 256U
 #define SD_MAX_VDI_TAG_LEN 256U
@@ -105,10 +105,13 @@
 #define SD_MAX_SNAPSHOT_TAG_LEN 256U
 #define SD_NR_VDIS   (1U << 24)
 #define SD_DATA_OBJ_SIZE (UINT64_C(1) << 22)
+#define SD_OLD_MAX_VDI_SIZE (SD_DATA_OBJ_SIZE * OLD_MAX_DATA_OBJS)
 #define SD_MAX_VDI_SIZE (SD_DATA_OBJ_SIZE * MAX_DATA_OBJS)
 
 #define SD_INODE_SIZE (sizeof(struct sd_inode))
 #define SD_INODE_INDEX_SIZE (sizeof(uint32_t) * MAX_DATA_OBJS)
+#define SD_INODE_DATA_INDEX (1ULL << 20)
+#define SD_INODE_DATA_INDEX_SIZE (sizeof(uint32_t) * SD_INODE_DATA_INDEX)
 #define SD_INODE_HEADER_SIZE offsetof(struct sd_inode, data_vdi_id)
 #define SD_ATTR_OBJ_SIZE (sizeof(struct sheepdog_vdi_attr))
 #define CURRENT_VDI_ID 0
@@ -142,7 +145,8 @@ struct sd_req {
 			uint32_t	base_vdi_id;
 			uint8_t		copies;
 			uint8_t		copy_policy;
-			uint8_t		reserved[2];
+			uint8_t		store_policy;
+			uint8_t		reserved;
 			uint32_t	snapid;
 		} vdi;
 
@@ -226,7 +230,7 @@ struct sd_inode {
 	uint32_t vdi_id;
 	uint32_t parent_vdi_id;
 	uint32_t child_vdi_id[MAX_CHILDREN];
-	uint32_t data_vdi_id[MAX_DATA_OBJS];
+	uint32_t data_vdi_id[SD_INODE_DATA_INDEX];
 	uint32_t btree_counter;
 };
 
@@ -264,6 +268,7 @@ struct sheepdog_vdi_attr {
 	char value[SD_MAX_VDI_ATTR_VALUE_LEN];
 };
 
+extern void sd_inode_init(void *data, int depth);
 extern uint32_t sd_inode_get_vid(read_node_fn reader,
 				 const struct sd_inode *inode, uint32_t idx);
 extern void sd_inode_set_vid(write_node_fn writer, read_node_fn reader,
diff --git a/lib/option.c b/lib/option.c
index d12c205..872a573 100644
--- a/lib/option.c
+++ b/lib/option.c
@@ -71,6 +71,9 @@ int option_parse_size(const char *value, uint64_t *ret)
 		goto err;
 
 	switch (*postfix) {
+	case 'P':
+	case 'p':
+		sizef *= 1024;
 	case 'T':
 	case 't':
 		sizef *= 1024;
@@ -90,8 +93,8 @@ int option_parse_size(const char *value, uint64_t *ret)
 	default:
 err:
 		sd_err("Invalid size '%s'", value);
-		sd_err("You may use k, M, G or T suffixes for "
-		       "kilobytes, megabytes, gigabytes and terabytes.");
+		sd_err("You may use k, M, G, T or P suffixes for "
+		       "kilobytes, megabytes, gigabytes, terabytes and petabytes.");
 		return -1;
 	}
 
diff --git a/lib/sd_inode.c b/lib/sd_inode.c
index b3e546d..26c9a3a 100644
--- a/lib/sd_inode.c
+++ b/lib/sd_inode.c
@@ -76,7 +76,8 @@
 #include "util.h"
 #include "sheepdog_proto.h"
 
-#define EXT_MAX_SPACE (SD_INODE_INDEX_SIZE - sizeof(struct sd_extent_header))
+#define EXT_MAX_SPACE (SD_INODE_DATA_INDEX_SIZE - \
+		sizeof(struct sd_extent_header))
 #define EXT_MAX_ENTRIES (EXT_MAX_SPACE / sizeof(struct sd_extent))
 #define EXT_IDX_MAX_ENTRIES (EXT_MAX_SPACE / sizeof(struct sd_extent_idx))
 
@@ -155,11 +156,12 @@ static void dump_btree(read_node_fn reader, struct sd_inode *inode)
 	} else if (header->depth == 2) {
 		last_idx = LAST_IDX(inode->data_vdi_id);
 		iter_idx = FIRST_IDX(inode->data_vdi_id);
-		leaf_node = xmalloc(SD_INODE_INDEX_SIZE);
+		leaf_node = xmalloc(SD_INODE_DATA_INDEX_SIZE);
 		tmp = (void *)leaf_node;
 
 		while (iter_idx != last_idx) {
-			reader(iter_idx->oid, &tmp, SD_INODE_INDEX_SIZE, 0);
+			reader(iter_idx->oid, &tmp,
+					SD_INODE_DATA_INDEX_SIZE, 0);
 
 			sd_info("btree> %p idx: %d, %lu, %u",
 					iter_idx, iter_idx->idx, iter_idx->oid,
@@ -205,7 +207,7 @@ static void *binary_search(void *first, void *last, void *key,
 	return (void *)l;
 }
 
-static void sd_inode_init(void *data, int depth)
+void sd_inode_init(void *data, int depth)
 {
 	struct sd_extent_header *header = EXT_HEADER(data);
 	header->magic = INODE_BTREE_MAGIC;
@@ -326,8 +328,8 @@ static void transfer_to_idx_root(write_node_fn writer, struct sd_inode *inode)
 	uint32_t num = root->entries / 2;
 
 	/* create two leaf-node and copy the entries from root-node */
-	left = xmalloc(SD_INODE_INDEX_SIZE);
-	right = xmalloc(SD_INODE_INDEX_SIZE);
+	left = xmalloc(SD_INODE_DATA_INDEX_SIZE);
+	right = xmalloc(SD_INODE_DATA_INDEX_SIZE);
 
 	split_to_nodes(root, left, right, num);
 
@@ -335,10 +337,10 @@ static void transfer_to_idx_root(write_node_fn writer, struct sd_inode *inode)
 	left_oid = vid_to_btree_oid(inode->vdi_id, inode->btree_counter++);
 	right_oid = vid_to_btree_oid(inode->vdi_id, inode->btree_counter++);
 
-	writer(left_oid, left, SD_INODE_INDEX_SIZE, 0, 0, inode->nr_copies,
-			inode->copy_policy, true, false);
-	writer(right_oid, right, SD_INODE_INDEX_SIZE, 0, 0, inode->nr_copies,
-			inode->copy_policy, true, false);
+	writer(left_oid, left, SD_INODE_DATA_INDEX_SIZE, 0, 0,
+	       inode->nr_copies, inode->copy_policy, true, false);
+	writer(right_oid, right, SD_INODE_DATA_INDEX_SIZE, 0, 0,
+	       inode->nr_copies, inode->copy_policy, true, false);
 
 	/* change root from ext-node to idx-node */
 	root->entries = 0;
@@ -368,12 +370,12 @@ static int search_whole_btree(read_node_fn reader, const struct sd_inode *inode,
 	if (header->depth == 2) {
 		path->depth = 2;
 		path->p_idx = search_idx_entry(header, idx);
-		leaf_node = xmalloc(SD_INODE_INDEX_SIZE);
+		leaf_node = xmalloc(SD_INODE_DATA_INDEX_SIZE);
 		tmp = (void *)leaf_node;
 
 		if (idx_in_range(header, path->p_idx)) {
 			oid = path->p_idx->oid;
-			ret = reader(oid, &tmp, SD_INODE_INDEX_SIZE, 0);
+			ret = reader(oid, &tmp, SD_INODE_DATA_INDEX_SIZE, 0);
 			if (ret != SD_RES_SUCCESS)
 				goto out;
 			path->p_ext = search_ext_entry(leaf_node, idx);
@@ -384,7 +386,7 @@ static int search_whole_btree(read_node_fn reader, const struct sd_inode *inode,
 		} else {
 			/* check if last idx-node has space */
 			oid = (path->p_idx - 1)->oid;
-			ret = reader(oid, &tmp, SD_INODE_INDEX_SIZE, 0);
+			ret = reader(oid, &tmp, SD_INODE_DATA_INDEX_SIZE, 0);
 			if (ret != SD_RES_SUCCESS)
 				goto out;
 			if (leaf_node->entries < EXT_MAX_ENTRIES) {
@@ -440,14 +442,14 @@ static void split_ext_node(write_node_fn writer, struct sd_inode *inode,
 	uint32_t num = old->entries / 2;
 	uint64_t new_oid;
 
-	new_ext = xmalloc(SD_INODE_INDEX_SIZE);
+	new_ext = xmalloc(SD_INODE_DATA_INDEX_SIZE);
 
 	split_to_nodes(old, new_ext, old, num);
 
 	new_oid = vid_to_btree_oid(inode->vdi_id, inode->btree_counter++);
-	writer(new_oid, new_ext, SD_INODE_INDEX_SIZE, 0, 0, inode->nr_copies,
-			inode->copy_policy, true, false);
-	writer(path->p_idx->oid, old, SD_INODE_INDEX_SIZE, 0, 0,
+	writer(new_oid, new_ext, SD_INODE_DATA_INDEX_SIZE, 0, 0,
+	       inode->nr_copies, inode->copy_policy, true, false);
+	writer(path->p_idx->oid, old, SD_INODE_DATA_INDEX_SIZE, 0, 0,
 	       inode->nr_copies, inode->copy_policy, false, false);
 
 	/* write new index */
@@ -492,8 +494,8 @@ static int insert_new_node(write_node_fn writer, read_node_fn reader,
 			insert_ext_entry_nosearch(path->p_ext_header,
 					path->p_ext, idx, vdi_id);
 			writer(path->p_idx->oid, path->p_ext_header,
-				SD_INODE_INDEX_SIZE, 0, 0, inode->nr_copies,
-				inode->copy_policy, true, false);
+			       SD_INODE_DATA_INDEX_SIZE, 0, 0, inode->nr_copies,
+			       inode->copy_policy, true, false);
 		} else if (path->p_ext_header) {
 			/* the last idx-node */
 			insert_ext_entry_nosearch(path->p_ext_header,
@@ -502,17 +504,17 @@ static int insert_new_node(write_node_fn writer, read_node_fn reader,
 			path->p_idx->idx =
 				(LAST_EXT(path->p_ext_header) - 1)->idx;
 			writer(path->p_idx->oid, path->p_ext_header,
-				SD_INODE_INDEX_SIZE, 0, 0, inode->nr_copies,
-				inode->copy_policy, true, false);
+			       SD_INODE_DATA_INDEX_SIZE, 0, 0, inode->nr_copies,
+			       inode->copy_policy, true, false);
 		} else {
 			/* create a new ext-node */
-			leaf_node = xmalloc(SD_INODE_INDEX_SIZE);
+			leaf_node = xmalloc(SD_INODE_DATA_INDEX_SIZE);
 			sd_inode_init(leaf_node, 2);
 			oid = vid_to_btree_oid(inode->vdi_id,
 					inode->btree_counter++);
 			insert_ext_entry_nosearch(leaf_node,
 					FIRST_EXT(leaf_node), idx, vdi_id);
-			writer(oid, leaf_node, SD_INODE_INDEX_SIZE,
+			writer(oid, leaf_node, SD_INODE_DATA_INDEX_SIZE,
 					0, 0, inode->nr_copies,
 					inode->copy_policy, true, false);
 			insert_idx_entry_nosearch(header, path->p_idx,
diff --git a/sheep/ops.c b/sheep/ops.c
index 32eac97..f55af94 100644
--- a/sheep/ops.c
+++ b/sheep/ops.c
@@ -84,6 +84,7 @@ static int cluster_new_vdi(struct request *req)
 		.base_vid = hdr->vdi.base_vdi_id,
 		.create_snapshot = !!hdr->vdi.snapid,
 		.copy_policy = hdr->vdi.copy_policy,
+		.store_policy = hdr->vdi.store_policy,
 		.nr_copies = hdr->vdi.copies,
 		.time = (uint64_t) tv.tv_sec << 32 | tv.tv_usec * 1000,
 	};
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index bd7e158..d333573 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -177,6 +177,7 @@ struct vdi_iocb {
 	uint32_t snapid;
 	bool create_snapshot;
 	uint8_t copy_policy;
+	uint8_t store_policy;
 	uint8_t nr_copies;
 	uint64_t time;
 };
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 99d4335..3d4af76 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -232,12 +232,15 @@ static struct sd_inode *alloc_inode(const struct vdi_iocb *iocb,
 	new->create_time = iocb->time;
 	new->vdi_size = iocb->size;
 	new->copy_policy = iocb->copy_policy;
+	new->store_policy = iocb->store_policy;
 	new->nr_copies = iocb->nr_copies;
 	new->block_size_shift = find_next_bit(&block_size, BITS_PER_LONG, 0);
 	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));
+	else if (new->store_policy)
+		sd_inode_init(new->data_vdi_id, 1);
 
 	return new;
 }
@@ -261,9 +264,9 @@ static int create_vdi(const struct vdi_iocb *iocb, uint32_t new_snapid,
 	int ret;
 
 	sd_debug("%s: size %" PRIu64 ", new_vid %" PRIx32 ", copies %d, "
-		 "snapid %" PRIu32 " copy policy %"PRIu8, iocb->name,
-		 iocb->size, new_vid, iocb->nr_copies, new_snapid,
-		 new->copy_policy);
+		 "snapid %" PRIu32 " copy policy %"PRIu8 "store policy %"PRIu8,
+		 iocb->name, iocb->size, new_vid, iocb->nr_copies, new_snapid,
+		 new->copy_policy, new->store_policy);
 
 	ret = write_object(vid_to_vdi_oid(new_vid), (char *)new, sizeof(*new),
 			   0, true);
-- 
1.7.1




More information about the sheepdog mailing list