[Sheepdog] [PATCH 1/2] add vdi creation time to the vdi attribute header
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Thu Oct 13 19:42:37 CEST 2011
Currently, Sheepdog doesn't clean up vdi attributes when we delete the
vdi. So if we create a new vdi whose name was used before, we could
read the old attribute.
This patch adds a vdi creation time to the attribute header and checks
whether the attribute belongs to the current vdi. Note that this is a
transitional approach. In future, we should remove vdi attributes when
we remove the vdi.
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
collie/vdi.c | 20 +++++++++---------
include/sheepdog_proto.h | 13 ++++++++++-
sheep/group.c | 26 ++++++++++++++++-------
sheep/sheep_priv.h | 9 ++++---
sheep/vdi.c | 49 +++++++++++++++++++++------------------------
5 files changed, 67 insertions(+), 50 deletions(-)
diff --git a/collie/vdi.c b/collie/vdi.c
index 27b0595..245a6e2 100644
--- a/collie/vdi.c
+++ b/collie/vdi.c
@@ -791,16 +791,16 @@ static int find_vdi_attr_oid(char *vdiname, char *tag, uint32_t snapid,
struct sd_vdi_rsp *rsp = (struct sd_vdi_rsp *)&hdr;
int fd, ret;
unsigned int wlen, rlen;
- char buf[SD_ATTR_HEADER_SIZE];
+ struct sheepdog_vdi_attr *vattr;
- memset(buf, 0, sizeof(buf));
- strncpy(buf, vdiname, SD_MAX_VDI_LEN);
- strncpy(buf + SD_MAX_VDI_LEN, vdi_cmd_data.snapshot_tag,
- SD_MAX_VDI_TAG_LEN);
- memcpy(buf + SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN,
- &vdi_cmd_data.snapshot_id, sizeof(uint32_t));
- strncpy(buf + SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN + sizeof(uint32_t),
- key, SD_MAX_VDI_ATTR_KEY_LEN);
+ vattr = zalloc(SD_ATTR_HEADER_SIZE);
+ if (!vattr)
+ return SD_RES_NO_MEM;
+
+ strncpy(vattr->name, vdiname, SD_MAX_VDI_LEN);
+ strncpy(vattr->tag, vdi_cmd_data.snapshot_tag, SD_MAX_VDI_TAG_LEN);
+ vattr->snap_id = vdi_cmd_data.snapshot_id;
+ strncpy(vattr->key, key, SD_MAX_VDI_ATTR_KEY_LEN);
fd = connect_to(sdhost, sdport);
if (fd < 0) {
@@ -821,7 +821,7 @@ static int find_vdi_attr_oid(char *vdiname, char *tag, uint32_t snapid,
if (excl)
hdr.flags |= SD_FLAG_CMD_EXCL;
- ret = exec_req(fd, (struct sd_req *)&hdr, buf, &wlen, &rlen);
+ ret = exec_req(fd, (struct sd_req *)&hdr, vattr, &wlen, &rlen);
if (ret) {
ret = SD_RES_EIO;
goto out;
diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index 2b042f4..bd34086 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -87,8 +87,7 @@
#define SD_INODE_SIZE (sizeof(struct sheepdog_inode))
#define SD_INODE_HEADER_SIZE (sizeof(struct sheepdog_inode) - \
sizeof(uint32_t) * MAX_DATA_OBJS)
-#define SD_ATTR_HEADER_SIZE (SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN + \
- sizeof(uint32_t) + SD_MAX_VDI_ATTR_KEY_LEN)
+#define SD_ATTR_HEADER_SIZE (sizeof(struct sheepdog_vdi_attr))
#define CURRENT_VDI_ID 0
struct sd_req {
@@ -185,6 +184,16 @@ struct sheepdog_inode {
uint32_t data_vdi_id[MAX_DATA_OBJS];
};
+struct sheepdog_vdi_attr {
+ char name[SD_MAX_VDI_LEN];
+ char tag[SD_MAX_VDI_TAG_LEN];
+ uint64_t ctime;
+ uint32_t snap_id;
+ uint32_t pad;
+ char key[SD_MAX_VDI_ATTR_KEY_LEN];
+ char value[0];
+};
+
/*
* 64 bit FNV-1a non-zero initial basis
*/
diff --git a/sheep/group.c b/sheep/group.c
index f6743f5..de3333e 100644
--- a/sheep/group.c
+++ b/sheep/group.c
@@ -850,9 +850,11 @@ static void vdi_op(struct vdi_op_message *msg)
{
const struct sd_vdi_req *hdr = &msg->req;
struct sd_vdi_rsp *rsp = &msg->rsp;
- void *data = msg->data;
+ void *data = msg->data, *tag;
int ret = SD_RES_SUCCESS;
+ struct sheepdog_vdi_attr *vattr;
uint32_t vid = 0, attrid = 0, nr_copies = sys->nr_sobjs;
+ uint64_t ctime = 0;
switch (hdr->opcode) {
case SD_OP_NEW_VDI:
@@ -870,23 +872,31 @@ static void vdi_op(struct vdi_op_message *msg)
ret = SD_RES_VER_MISMATCH;
break;
}
- ret = lookup_vdi(hdr->epoch, data, hdr->data_length, &vid,
- hdr->snapid, &nr_copies);
+ if (hdr->data_length == SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN)
+ tag = (char *)data + SD_MAX_VDI_LEN;
+ else if (hdr->data_length == SD_MAX_VDI_LEN)
+ tag = NULL;
+ else {
+ ret = SD_RES_INVALID_PARMS;
+ break;
+ }
+ ret = lookup_vdi(hdr->epoch, data, tag, &vid, hdr->snapid,
+ &nr_copies, NULL);
if (ret != SD_RES_SUCCESS)
break;
break;
case SD_OP_GET_VDI_ATTR:
- ret = lookup_vdi(hdr->epoch, data,
- min(SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN, hdr->data_length),
- &vid, hdr->snapid, &nr_copies);
+ vattr = data;
+ ret = lookup_vdi(hdr->epoch, vattr->name, vattr->tag,
+ &vid, hdr->snapid, &nr_copies, &ctime);
if (ret != SD_RES_SUCCESS)
break;
/* the curernt vdi id can change if we take the snapshot,
so we use the hash value of the vdi name as the vdi id */
- vid = fnv_64a_buf(data, strlen(data), FNV1A_64_INIT);
+ vid = fnv_64a_buf(vattr->name, strlen(vattr->name), FNV1A_64_INIT);
vid &= SD_NR_VDIS - 1;
ret = get_vdi_attr(hdr->epoch, data, hdr->data_length, vid,
- &attrid, nr_copies,
+ &attrid, nr_copies, ctime,
hdr->flags & SD_FLAG_CMD_CREAT,
hdr->flags & SD_FLAG_CMD_EXCL);
break;
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index e2fcb40..6ea03d5 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -174,13 +174,14 @@ int add_vdi(uint32_t epoch, char *data, int data_len, uint64_t size,
int del_vdi(uint32_t epoch, char *data, int data_len, uint32_t *vid,
uint32_t snapid, unsigned int *nr_copies);
-int lookup_vdi(uint32_t epoch, char *data, int data_len, uint32_t *vid,
- uint32_t snapid, unsigned int *nr_copies);
+int lookup_vdi(uint32_t epoch, char *name, char *tag, uint32_t *vid,
+ uint32_t snapid, unsigned int *nr_copies, uint64_t *ctime);
int read_vdis(char *data, int len, unsigned int *rsp_len);
-int get_vdi_attr(uint32_t epoch, char *data, int data_len, uint32_t vid,
- uint32_t *attrid, int copies, int creat, int excl);
+int get_vdi_attr(uint32_t epoch, struct sheepdog_vdi_attr *vattr, int data_len,
+ uint32_t vid, uint32_t *attrid, int copies, uint64_t ctime,
+ int creat, int excl);
int get_ordered_sd_node_list(struct sheepdog_node_list_entry *entries);
void setup_ordered_sd_vnode_list(struct request *req);
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 392d429..87a63c9 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -159,7 +159,7 @@ out:
static int find_first_vdi(uint32_t epoch, unsigned long start, unsigned long end,
char *name, char *tag, uint32_t snapid, uint32_t *vid,
unsigned long *deleted_nr, uint32_t *next_snap,
- unsigned int *nr_copies)
+ unsigned int *nr_copies, uint64_t *ctime)
{
struct sheepdog_vnode_list_entry *entries;
struct sheepdog_inode *inode = NULL;
@@ -206,6 +206,8 @@ static int find_first_vdi(uint32_t epoch, unsigned long start, unsigned long end
*next_snap = inode->snap_id + 1;
*vid = inode->vdi_id;
*nr_copies = inode->nr_copies;
+ if (ctime)
+ *ctime = inode->ctime;
ret = SD_RES_SUCCESS;
goto out;
}
@@ -226,7 +228,7 @@ out:
static int do_lookup_vdi(uint32_t epoch, char *name, int namelen, uint32_t *vid,
char *tag, uint32_t snapid, uint32_t *next_snapid,
unsigned long *right_nr, unsigned long *deleted_nr,
- unsigned int *nr_copies)
+ unsigned int *nr_copies, uint64_t *ctime)
{
int ret;
unsigned long nr, start_nr;
@@ -244,7 +246,7 @@ static int do_lookup_vdi(uint32_t epoch, char *name, int namelen, uint32_t *vid,
right_side:
/* look up on the right side of the hash point */
ret = find_first_vdi(epoch, nr - 1, start_nr, name, tag, snapid, vid,
- deleted_nr, next_snapid, nr_copies);
+ deleted_nr, next_snapid, nr_copies, ctime);
return ret;
} else {
/* round up... bitmap search from the head of the bitmap */
@@ -255,7 +257,7 @@ static int do_lookup_vdi(uint32_t epoch, char *name, int namelen, uint32_t *vid,
else if (nr) {
/* look up on the left side of the hash point */
ret = find_first_vdi(epoch, nr - 1, 0, name, tag, snapid, vid,
- deleted_nr, next_snapid, nr_copies);
+ deleted_nr, next_snapid, nr_copies, ctime);
if (ret == SD_RES_NO_VDI)
; /* we need to go to the right side */
else
@@ -267,22 +269,14 @@ static int do_lookup_vdi(uint32_t epoch, char *name, int namelen, uint32_t *vid,
}
}
-int lookup_vdi(uint32_t epoch, char *data, int data_len, uint32_t *vid,
- uint32_t snapid, unsigned int *nr_copies)
+int lookup_vdi(uint32_t epoch, char *name, char *tag, uint32_t *vid,
+ uint32_t snapid, unsigned int *nr_copies, uint64_t *ctime)
{
- char *name = data, *tag;
uint32_t dummy0;
unsigned long dummy1, dummy2;
- if (data_len == SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN)
- tag = data + SD_MAX_VDI_LEN;
- else if (data_len == SD_MAX_VDI_LEN)
- tag = NULL;
- else
- return SD_RES_INVALID_PARMS;
-
return do_lookup_vdi(epoch, name, strlen(name), vid, tag, snapid,
- &dummy0, &dummy1, &dummy2, nr_copies);
+ &dummy0, &dummy1, &dummy2, nr_copies, ctime);
}
int add_vdi(uint32_t epoch, char *data, int data_len, uint64_t size,
@@ -301,7 +295,7 @@ int add_vdi(uint32_t epoch, char *data, int data_len, uint64_t size,
name = data;
ret = do_lookup_vdi(epoch, name, strlen(name), &cur_vid, NULL, 0, &next_snapid,
- &right_nr, &deleted_nr, nr_copies);
+ &right_nr, &deleted_nr, nr_copies, NULL);
if (is_snapshot) {
if (ret != SD_RES_SUCCESS) {
@@ -375,7 +369,7 @@ int del_vdi(uint32_t epoch, char *data, int data_len, uint32_t *vid,
}
ret = do_lookup_vdi(epoch, name, strlen(name), vid, tag, snapid,
- &dummy0, &dummy1, &dummy2, nr_copies);
+ &dummy0, &dummy1, &dummy2, nr_copies, NULL);
if (ret != SD_RES_SUCCESS)
goto out;
@@ -658,11 +652,12 @@ err:
return ret;
}
-int get_vdi_attr(uint32_t epoch, char *data, int data_len, uint32_t vid,
- uint32_t *attrid, int copies, int creat, int excl)
+int get_vdi_attr(uint32_t epoch, struct sheepdog_vdi_attr *vattr, int data_len,
+ uint32_t vid, uint32_t *attrid, int copies, uint64_t ctime,
+ int creat, int excl)
{
struct sheepdog_vnode_list_entry *entries;
- char attr_buf[SD_ATTR_HEADER_SIZE];
+ struct sheepdog_vdi_attr tmp_attr;
uint64_t oid;
uint32_t end;
int ret, nr_zones, nr_vnodes;
@@ -679,20 +674,22 @@ int get_vdi_attr(uint32_t epoch, char *data, int data_len, uint32_t vid,
goto out;
}
+ vattr->ctime = ctime;
+
get_ordered_sd_vnode_list(entries, &nr_vnodes, &nr_zones);
- *attrid = fnv_64a_buf(data, data_len, FNV1A_64_INIT);
+ *attrid = fnv_64a_buf(vattr, data_len, FNV1A_64_INIT);
*attrid &= (UINT64_C(1) << VDI_SPACE_SHIFT) - 1;
end = *attrid - 1;
while (*attrid != end) {
oid = vid_to_attr_oid(vid, *attrid);
- ret = read_object(entries, nr_vnodes, nr_zones, epoch, oid, attr_buf,
- sizeof(attr_buf), 0, copies);
+ ret = read_object(entries, nr_vnodes, nr_zones, epoch, oid, (char *)&tmp_attr,
+ sizeof(tmp_attr), 0, copies);
if (ret == -SD_RES_NO_OBJ && creat) {
- ret = write_object(entries, nr_vnodes, nr_zones, epoch, oid, data,
- data_len, 0, copies, 1);
+ ret = write_object(entries, nr_vnodes, nr_zones, epoch, oid,
+ (char *)vattr, data_len, 0, copies, 1);
if (ret)
ret = SD_RES_EIO;
else
@@ -703,7 +700,7 @@ int get_vdi_attr(uint32_t epoch, char *data, int data_len, uint32_t vid,
if (ret < 0)
return -ret;
- if (memcmp(attr_buf, data, sizeof(attr_buf)) == 0) {
+ if (memcmp(&tmp_attr, vattr, sizeof(tmp_attr)) == 0) {
if (excl)
ret = SD_RES_VDI_EXIST;
else
--
1.7.2.5
More information about the sheepdog
mailing list