[sheepdog] [PATCH 1/5] dog/farm: register vdi for 'snapshot load operation'
Liu Yuan
namei.unix at gmail.com
Thu Feb 27 06:48:04 CET 2014
This will git rid of need that we have to manually check copy_policy of requests
in the plain store.
Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
dog/farm/farm.c | 141 ++++++++++++++++++++++++++++++--------------------------
1 file changed, 75 insertions(+), 66 deletions(-)
diff --git a/dog/farm/farm.c b/dog/farm/farm.c
index 00895af..7d93406 100644
--- a/dog/farm/farm.c
+++ b/dog/farm/farm.c
@@ -21,8 +21,16 @@
static char farm_object_dir[PATH_MAX];
static char farm_dir[PATH_MAX];
-static struct sd_rw_lock vdi_list_lock = SD_RW_LOCK_INITIALIZER;
-struct vdi_entry {
+static struct sd_rw_lock active_vdi_lock = SD_RW_LOCK_INITIALIZER;
+static struct sd_rw_lock registered_vdi_lock = SD_RW_LOCK_INITIALIZER;
+
+struct registered_vdi_entry {
+ struct rb_node rb;
+ uint32_t vid;
+};
+
+struct active_vdi_entry {
+ struct rb_node rb;
char name[SD_MAX_VDI_LEN];
uint64_t vdi_size;
uint32_t vdi_id;
@@ -30,9 +38,12 @@ struct vdi_entry {
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;
+
+/* We use active_vdi_tree to create active vdi on top of the snapshot chain */
+static struct rb_root active_vdi_tree = RB_ROOT;
+/* We have to register vdi information first before loading objects */
+static struct rb_root registered_vdi_tree = RB_ROOT;
struct snapshot_work {
struct trunk_entry entry;
@@ -42,65 +53,71 @@ struct snapshot_work {
static struct work_queue *wq;
static uatomic_bool work_error;
-static int vdi_cmp(const struct vdi_entry *e1, const struct vdi_entry *e2)
+static int vdi_cmp(const struct active_vdi_entry *e1,
+ const struct active_vdi_entry *e2)
{
return strcmp(e1->name, e2->name);
}
-static struct vdi_entry *find_vdi(const char *name)
+static void update_active_vdi_entry(struct active_vdi_entry *vdi,
+ struct sd_inode *new)
{
- struct vdi_entry key = {};
+ pstrcpy(vdi->name, sizeof(vdi->name), new->name);
+ vdi->vdi_size = new->vdi_size;
+ vdi->vdi_id = new->vdi_id;
+ vdi->snap_id = new->snap_id;
+ vdi->nr_copies = new->nr_copies;
+ vdi->copy_policy = new->copy_policy;
+ vdi->store_policy = new->store_policy;
+}
+
+static void add_active_vdi(struct sd_inode *new)
+{
+ struct active_vdi_entry *vdi, *ret;
- pstrcpy(key.name, sizeof(key.name), name);
+ vdi = xmalloc(sizeof(struct active_vdi_entry));
- return rb_search(&last_vdi_tree, &key, rb, vdi_cmp);
+ update_active_vdi_entry(vdi, new);
+ sd_write_lock(&active_vdi_lock);
+ ret = rb_insert(&active_vdi_tree, vdi, rb, vdi_cmp);
+ if (ret && ret->snap_id < new->snap_id) {
+ update_active_vdi_entry(ret, new);
+ free(vdi);
+ }
+ sd_rw_unlock(&active_vdi_lock);
}
-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 store_policy)
+static int registered_vdi_cmp(struct registered_vdi_entry *a,
+ struct registered_vdi_entry *b)
{
- struct vdi_entry *vdi;
- vdi = xmalloc(sizeof(struct vdi_entry));
- pstrcpy(vdi->name, sizeof(vdi->name), name);
- vdi->vdi_size = vdi_size;
- vdi->vdi_id = vdi_id;
- vdi->snap_id = snap_id;
- vdi->nr_copies = nr_copies;
- vdi->copy_policy = copy_policy;
- vdi->store_policy = store_policy;
- return vdi;
+ return intcmp(a->vid, b->vid);
}
-static void insert_vdi(struct sd_inode *new)
+static bool register_vdi(uint32_t vid)
{
- struct vdi_entry *vdi;
- vdi = find_vdi(new->name);
- if (!vdi) {
- vdi = new_vdi(new->name,
- new->vdi_size,
- new->vdi_id,
- new->snap_id,
- new->nr_copies,
- 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;
- vdi->vdi_id = new->vdi_id;
- vdi->snap_id = new->snap_id;
- vdi->nr_copies = new->nr_copies;
- vdi->copy_policy = new->copy_policy;
- vdi->store_policy = new->store_policy;
+ struct registered_vdi_entry *new = xmalloc(sizeof(*new)), *ret;
+
+ new->vid = vid;
+
+ sd_read_lock(®istered_vdi_lock);
+ ret = rb_search(®istered_vdi_tree, new, rb, registered_vdi_cmp);
+ sd_rw_unlock(®istered_vdi_lock);
+ if (ret) {
+ free(new);
+ return false;
}
+
+ sd_write_lock(®istered_vdi_lock);
+ rb_insert(®istered_vdi_tree, new, rb, registered_vdi_cmp);
+ sd_rw_unlock(®istered_vdi_lock);
+ return true;
}
static int create_active_vdis(void)
{
- struct vdi_entry *vdi;
+ struct active_vdi_entry *vdi;
uint32_t new_vid;
- rb_for_each_entry(vdi, &last_vdi_tree, rb) {
+ rb_for_each_entry(vdi, &active_vdi_tree, rb) {
if (do_vdi_create(vdi->name,
vdi->vdi_size,
vdi->vdi_id, &new_vid,
@@ -112,15 +129,6 @@ static int create_active_vdis(void)
return 0;
}
-static void free_vdi_list(void)
-{
- struct vdi_entry *vdi;
- rb_for_each_entry(vdi, &last_vdi_tree, rb) {
- rb_erase(&vdi->rb, &last_vdi_tree);
- free(vdi);
- }
-}
-
char *get_object_directory(void)
{
return farm_object_dir;
@@ -353,6 +361,7 @@ static void do_load_object(struct work *work)
size_t size;
struct snapshot_work *sw;
static unsigned long loaded;
+ uint32_t vid;
if (uatomic_is_true(&work_error))
return;
@@ -364,22 +373,21 @@ static void do_load_object(struct work *work)
if (!buffer)
goto error;
- if (dog_write_object(sw->entry.oid, 0, buffer, size, 0, 0,
- sw->entry.nr_copies, sw->entry.copy_policy,
- true, true) != 0)
- goto error;
-
- if (is_vdi_obj(sw->entry.oid)) {
- if (notify_vdi_add(oid_to_vid(sw->entry.oid),
- sw->entry.nr_copies,
+ vid = oid_to_vid(sw->entry.oid);
+ if (register_vdi(vid)) {
+ if (notify_vdi_add(vid, sw->entry.nr_copies,
sw->entry.copy_policy) < 0)
goto error;
-
- sd_write_lock(&vdi_list_lock);
- insert_vdi(buffer);
- sd_rw_unlock(&vdi_list_lock);
}
+ if (dog_write_object(sw->entry.oid, 0, buffer, size, 0, 0,
+ sw->entry.nr_copies, sw->entry.copy_policy,
+ true, true) != 0)
+ goto error;
+
+ if (is_vdi_obj(sw->entry.oid))
+ add_active_vdi(buffer);
+
farm_show_progress(uatomic_add_return(&loaded, 1), trunk_get_count());
free(buffer);
return;
@@ -431,6 +439,7 @@ int farm_load_snapshot(uint32_t idx, const char *tag)
ret = 0;
out:
- free_vdi_list();
+ rb_destroy(&active_vdi_tree, struct active_vdi_entry, rb);
+ rb_destroy(®istered_vdi_tree, struct registered_vdi_entry, rb);
return ret;
}
--
1.8.1.2
More information about the sheepdog
mailing list