From: MORITA Kazutaka <morita.kazut...@lab.ntt.co.jp>

This renames vdi_copy to vdi_state and adds a new field 'snapshot' to
it so that we can know whether the vdi is snapshot or not.

Signed-off-by: MORITA Kazutaka <morita.kazut...@lab.ntt.co.jp>
---
 include/sheep.h          |    5 ---
 include/sheepdog_proto.h |    5 +++
 sheep/group.c            |   14 +++----
 sheep/ops.c              |   11 ++++--
 sheep/plain_store.c      |    7 ++--
 sheep/sheep_priv.h       |   11 +++++-
 sheep/vdi.c              |   91 +++++++++++++++++++++++-----------------------
 7 files changed, 77 insertions(+), 67 deletions(-)

diff --git a/include/sheep.h b/include/sheep.h
index 26b9639..1c3d847 100644
--- a/include/sheep.h
+++ b/include/sheep.h
@@ -36,11 +36,6 @@ struct vnode_info {
        int refcnt;
 };
 
-struct vdi_copy {
-       uint32_t vid;
-       uint32_t nr_copies;
-};
-
 #define TRACE_GRAPH_ENTRY  0x01
 #define TRACE_GRAPH_RETURN 0x02
 
diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index 886b535..aef97dd 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -138,6 +138,11 @@ struct sd_req {
                        uint32_t        copies;
                        uint32_t        tag;
                } cluster;
+               struct {
+                       uint32_t        old_vid;
+                       uint32_t        new_vid;
+                       uint32_t        copies;
+               } vdi_state;
 
                uint32_t                __pad[8];
        };
diff --git a/sheep/group.c b/sheep/group.c
index 4044d12..bb5d703 100644
--- a/sheep/group.c
+++ b/sheep/group.c
@@ -647,7 +647,7 @@ static int get_vdis_from(struct sd_node *node)
 {
        struct sd_req hdr;
        struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
-       struct vdi_copy *vc = NULL;
+       struct vdi_state *vs = NULL;
        int i, ret = SD_RES_SUCCESS;
        unsigned int rlen;
        int count;
@@ -656,21 +656,21 @@ static int get_vdis_from(struct sd_node *node)
                goto out;
 
        rlen = SD_DATA_OBJ_SIZE; /* FIXME */
-       vc = xzalloc(rlen);
+       vs = xzalloc(rlen);
        sd_init_req(&hdr, SD_OP_GET_VDI_COPIES);
        hdr.data_length = rlen;
        hdr.epoch = sys_epoch();
-       ret = sheep_exec_req(&node->nid, &hdr, (char *)vc);
+       ret = sheep_exec_req(&node->nid, &hdr, (char *)vs);
        if (ret != SD_RES_SUCCESS)
                goto out;
 
-       count = rsp->data_length / sizeof(*vc);
+       count = rsp->data_length / sizeof(*vs);
        for (i = 0; i < count; i++) {
-               set_bit(vc[i].vid, sys->vdi_inuse);
-               add_vdi_copy_number(vc[i].vid, vc[i].nr_copies);
+               set_bit(vs[i].vid, sys->vdi_inuse);
+               add_vdi_state(vs[i].vid, vs[i].nr_copies, vs[i].snapshot);
        }
 out:
-       free(vc);
+       free(vs);
        return ret;
 }
 
diff --git a/sheep/ops.c b/sheep/ops.c
index 48dd08c..7f27bc3 100644
--- a/sheep/ops.c
+++ b/sheep/ops.c
@@ -390,7 +390,7 @@ static int local_read_vdis(const struct sd_req *req, struct 
sd_rsp *rsp,
 static int local_get_vdi_copies(const struct sd_req *req, struct sd_rsp *rsp,
                           void *data)
 {
-       rsp->data_length = fill_vdi_copy_list(data);
+       rsp->data_length = fill_vdi_state_list(data);
 
        return SD_RES_SUCCESS;
 }
@@ -618,10 +618,13 @@ static int cluster_cleanup(const struct sd_req *req, 
struct sd_rsp *rsp,
 static int cluster_notify_vdi_add(const struct sd_req *req, struct sd_rsp *rsp,
                                  void *data)
 {
-       uint32_t vid = *(uint32_t *)data;
-       uint32_t nr_copies = *(uint32_t *)((char *)data + sizeof(vid));
+       if (req->vdi_state.old_vid)
+               /* make the previous working vdi a snapshot */
+               add_vdi_state(req->vdi_state.old_vid,
+                             get_vdi_copy_number(req->vdi_state.old_vid),
+                             true);
 
-       add_vdi_copy_number(vid, nr_copies);
+       add_vdi_state(req->vdi_state.new_vid, req->vdi_state.copies, false);
 
        return SD_RES_SUCCESS;
 }
diff --git a/sheep/plain_store.c b/sheep/plain_store.c
index b539df1..640f769 100644
--- a/sheep/plain_store.c
+++ b/sheep/plain_store.c
@@ -168,7 +168,7 @@ int default_cleanup(void)
        return SD_RES_SUCCESS;
 }
 
-static int init_vdi_copy_number(uint64_t oid, char *wd)
+static int init_vdi_state(uint64_t oid, char *wd)
 {
        char path[PATH_MAX];
        int fd, flags = get_open_flags(oid, false, 0), ret;
@@ -190,7 +190,8 @@ static int init_vdi_copy_number(uint64_t oid, char *wd)
                goto out;
        }
 
-       add_vdi_copy_number(oid_to_vid(oid), inode->nr_copies);
+       add_vdi_state(oid_to_vid(oid), inode->nr_copies,
+                     vdi_is_snapshot(inode));
 
        ret = SD_RES_SUCCESS;
 out:
@@ -206,7 +207,7 @@ static int init_objlist_and_vdi_bitmap(uint64_t oid, char 
*wd, void *arg)
        if (is_vdi_obj(oid)) {
                sd_dprintf("found the VDI object %" PRIx64, oid);
                set_bit(oid_to_vid(oid), sys->vdi_inuse);
-               ret = init_vdi_copy_number(oid, wd);
+               ret = init_vdi_state(oid, wd);
                if (ret != SD_RES_SUCCESS)
                        return ret;
        }
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index 1fc291c..99b44a2 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -149,6 +149,13 @@ struct vdi_info {
        uint64_t create_time;
 };
 
+struct vdi_state {
+       uint32_t vid;
+       uint8_t nr_copies;
+       uint8_t snapshot;
+       uint16_t _pad;
+};
+
 struct store_driver {
        struct list_head list;
        const char *name;
@@ -252,12 +259,12 @@ int init_base_path(const char *dir);
 int init_disk_space(const char *d);
 int lock_base_dir(const char *d);
 
-int fill_vdi_copy_list(void *data);
+int fill_vdi_state_list(void *data);
 int get_vdi_copy_number(uint32_t vid);
 int get_obj_copy_number(uint64_t oid, int nr_zones);
 int get_max_copy_number(void);
 int get_req_copy_number(struct request *req);
-int add_vdi_copy_number(uint32_t vid, int nr_copies);
+int add_vdi_state(uint32_t vid, int nr_copies, bool snapshot);
 int vdi_exist(uint32_t vid);
 int vdi_create(struct vdi_iocb *iocb, uint32_t *new_vid);
 int vdi_delete(struct vdi_iocb *iocb, struct request *req);
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 057dd5a..3085148 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -16,24 +16,25 @@
 #include "sheepdog_proto.h"
 #include "sheep_priv.h"
 
-struct vdi_copy_entry {
+struct vdi_state_entry {
        uint32_t vid;
        unsigned int nr_copies;
+       bool snapshot;
        struct rb_node node;
 };
 
 static uint32_t max_copies;
-static struct rb_root vdi_copy_root = RB_ROOT;
-static pthread_rwlock_t vdi_copy_lock = PTHREAD_RWLOCK_INITIALIZER;
+static struct rb_root vdi_state_root = RB_ROOT;
+static pthread_rwlock_t vdi_state_lock = PTHREAD_RWLOCK_INITIALIZER;
 
-static struct vdi_copy_entry *vdi_copy_search(struct rb_root *root,
-                                             uint32_t vid)
+static struct vdi_state_entry *vdi_state_search(struct rb_root *root,
+                                               uint32_t vid)
 {
        struct rb_node *n = root->rb_node;
-       struct vdi_copy_entry *t;
+       struct vdi_state_entry *t;
 
        while (n) {
-               t = rb_entry(n, struct vdi_copy_entry, node);
+               t = rb_entry(n, struct vdi_state_entry, node);
 
                if (vid < t->vid)
                        n = n->rb_left;
@@ -46,16 +47,16 @@ static struct vdi_copy_entry *vdi_copy_search(struct 
rb_root *root,
        return NULL;
 }
 
-static struct vdi_copy_entry *vdi_copy_insert(struct rb_root *root,
-                                             struct vdi_copy_entry *new)
+static struct vdi_state_entry *vdi_state_insert(struct rb_root *root,
+                                               struct vdi_state_entry *new)
 {
        struct rb_node **p = &root->rb_node;
        struct rb_node *parent = NULL;
-       struct vdi_copy_entry *entry;
+       struct vdi_state_entry *entry;
 
        while (*p) {
                parent = *p;
-               entry = rb_entry(parent, struct vdi_copy_entry, node);
+               entry = rb_entry(parent, struct vdi_state_entry, node);
 
                if (new->vid < entry->vid)
                        p = &(*p)->rb_left;
@@ -72,11 +73,11 @@ static struct vdi_copy_entry *vdi_copy_insert(struct 
rb_root *root,
 
 int get_vdi_copy_number(uint32_t vid)
 {
-       struct vdi_copy_entry *entry;
+       struct vdi_state_entry *entry;
 
-       pthread_rwlock_rdlock(&vdi_copy_lock);
-       entry = vdi_copy_search(&vdi_copy_root, vid);
-       pthread_rwlock_unlock(&vdi_copy_lock);
+       pthread_rwlock_rdlock(&vdi_state_lock);
+       entry = vdi_state_search(&vdi_state_root, vid);
+       pthread_rwlock_unlock(&vdi_state_lock);
 
        if (!entry) {
                sd_eprintf("No VDI copy entry for %" PRIx32 " found", vid);
@@ -113,50 +114,54 @@ int get_max_copy_number(void)
        return nr_copies;
 }
 
-int add_vdi_copy_number(uint32_t vid, int nr_copies)
+int add_vdi_state(uint32_t vid, int nr_copies, bool snapshot)
 {
-       struct vdi_copy_entry *entry, *old;
+       struct vdi_state_entry *entry, *old;
 
        entry = xzalloc(sizeof(*entry));
        entry->vid = vid;
        entry->nr_copies = nr_copies;
+       entry->snapshot = snapshot;
 
        sd_dprintf("%" PRIx32 ", %d", vid, nr_copies);
 
-       pthread_rwlock_wrlock(&vdi_copy_lock);
-       old = vdi_copy_insert(&vdi_copy_root, entry);
+       pthread_rwlock_wrlock(&vdi_state_lock);
+       old = vdi_state_insert(&vdi_state_root, entry);
        if (old) {
                free(entry);
                entry = old;
                entry->nr_copies = nr_copies;
+               entry->snapshot = snapshot;
        }
 
        if (uatomic_read(&max_copies) == 0 ||
            nr_copies > uatomic_read(&max_copies))
                uatomic_set(&max_copies, nr_copies);
-       pthread_rwlock_unlock(&vdi_copy_lock);
+       pthread_rwlock_unlock(&vdi_state_lock);
 
        return SD_RES_SUCCESS;
 }
 
-int fill_vdi_copy_list(void *data)
+int fill_vdi_state_list(void *data)
 {
        int nr = 0;
        struct rb_node *n;
-       struct vdi_copy *vc = data;
-       struct vdi_copy_entry *entry;
-
-       pthread_rwlock_rdlock(&vdi_copy_lock);
-       for (n = rb_first(&vdi_copy_root); n; n = rb_next(n)) {
-               entry = rb_entry(n, struct vdi_copy_entry, node);
-               vc->vid = entry->vid;
-               vc->nr_copies = entry->nr_copies;
-               vc++;
+       struct vdi_state *vs = data;
+       struct vdi_state_entry *entry;
+
+       pthread_rwlock_rdlock(&vdi_state_lock);
+       for (n = rb_first(&vdi_state_root); n; n = rb_next(n)) {
+               entry = rb_entry(n, struct vdi_state_entry, node);
+               memset(vs, 0, sizeof(*vs));
+               vs->vid = entry->vid;
+               vs->nr_copies = entry->nr_copies;
+               vs->snapshot = entry->snapshot;
+               vs++;
                nr++;
        }
-       pthread_rwlock_unlock(&vdi_copy_lock);
+       pthread_rwlock_unlock(&vdi_state_lock);
 
-       return nr * sizeof(*vc);
+       return nr * sizeof(*vs);
 }
 
 static inline bool vdi_is_deleted(struct sd_inode *inode)
@@ -443,26 +448,20 @@ int vdi_lookup(struct vdi_iocb *iocb, struct vdi_info 
*info)
        return fill_vdi_info(left, right, iocb, info);
 }
 
-static int notify_vdi_add(uint32_t vdi_id, uint32_t nr_copies)
+static int notify_vdi_add(uint32_t vdi_id, uint32_t nr_copies, uint32_t 
old_vid)
 {
        int ret = SD_RES_SUCCESS;
        struct sd_req hdr;
-       char *buf;
 
        sd_init_req(&hdr, SD_OP_NOTIFY_VDI_ADD);
-       hdr.flags = SD_FLAG_CMD_WRITE;
-       hdr.data_length = sizeof(vdi_id) + sizeof(nr_copies);
-
-       buf = xmalloc(sizeof(vdi_id) + sizeof(nr_copies));
-       memcpy(buf, &vdi_id, sizeof(vdi_id));
-       memcpy(buf + sizeof(vdi_id), &nr_copies, sizeof(nr_copies));
+       hdr.vdi_state.old_vid = old_vid;
+       hdr.vdi_state.new_vid = vdi_id;
+       hdr.vdi_state.copies = nr_copies;
 
-       ret = exec_local_req(&hdr, buf);
+       ret = exec_local_req(&hdr, NULL);
        if (ret != SD_RES_SUCCESS)
-               sd_eprintf("fail to notify vdi add event(%" PRIx32 ", %d)",
-                          vdi_id, nr_copies);
-
-       free(buf);
+               sd_eprintf("fail to notify vdi add event(%" PRIx32 ", %d, %"
+                          PRIx32 ")", vdi_id, nr_copies, old_vid);
 
        return ret;
 }
@@ -499,7 +498,7 @@ int vdi_create(struct vdi_iocb *iocb, uint32_t *new_vid)
        if (!iocb->snapid)
                iocb->snapid = 1;
        *new_vid = info.free_bit;
-       notify_vdi_add(*new_vid, iocb->nr_copies);
+       notify_vdi_add(*new_vid, iocb->nr_copies, info.vid);
 
        sd_dprintf("%s %s: size %" PRIu64 ", vid %" PRIx32 ", base %" PRIx32
                   ", cur %" PRIx32 ", copies %d, snapid %"PRIu32,
-- 
1.7.9.5

-- 
sheepdog mailing list
sheepdog@lists.wpkg.org
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to