[sheepdog] [PATCH v3 2/5] add basic read/write function framwork for btree
Robin Dong
robin.k.dong at gmail.com
Thu Oct 24 11:46:19 CEST 2013
B-tree is just a abstract structure so it need to call callback-function to read
and write nodes.
Signed-off-by: Robin Dong <sanbai at taobao.com>
---
dog/cluster.c | 2 +-
dog/dog.h | 9 +++++++++
dog/vdi.c | 38 ++++++++++++++++++++++++++++----------
include/sheepdog_proto.h | 18 +++++++++---------
lib/sd_inode.c | 6 ++++--
sheep/sheep_priv.h | 9 +++++++++
sheep/vdi.c | 13 ++++++++++++-
sheepfs/volume.c | 39 +++++++++++++++++++++++++++++++++++++--
8 files changed, 109 insertions(+), 25 deletions(-)
diff --git a/dog/cluster.c b/dog/cluster.c
index 62b78d0..b432302 100644
--- a/dog/cluster.c
+++ b/dog/cluster.c
@@ -259,7 +259,7 @@ static void fill_object_tree(uint32_t vid, const char *name, const char *tag,
/* fill data object id */
nr_objs = count_data_objs(i);
for (uint64_t idx = 0; idx < nr_objs; idx++) {
- vdi_id = sd_inode_get_vdi(i, idx);
+ vdi_id = INODE_GET_VDI(i, idx);
if (vdi_id) {
uint64_t oid = vid_to_data_oid(vdi_id, idx);
object_tree_insert(oid, i->nr_copies, i->copy_policy);
diff --git a/dog/dog.h b/dog/dog.h
index 769fc6c..c2832bb 100644
--- a/dog/dog.h
+++ b/dog/dog.h
@@ -85,6 +85,15 @@ void show_progress(uint64_t done, uint64_t total, bool raw);
size_t get_store_objsize(uint8_t copy_policy, uint64_t oid);
bool is_erasure_oid(uint64_t oid, uint8_t policy);
+int write_btree_node(uint64_t id, void *mem, unsigned int len,
+ int copies, int copy_policy, int create);
+int read_btree_node(uint64_t id, void **mem, unsigned int len);
+
+#define INODE_GET_VDI(inode, idx) (sd_inode_get_vdi(read_btree_node, \
+ inode, idx))
+#define INODE_SET_VDI(inode, idx, vdi_id) (sd_inode_set_vdi(write_btree_node, \
+ read_btree_node, inode, idx, vdi_id))
+
extern struct command vdi_command;
extern struct command node_command;
extern struct command cluster_command;
diff --git a/dog/vdi.c b/dog/vdi.c
index c50f886..faf06f0 100644
--- a/dog/vdi.c
+++ b/dog/vdi.c
@@ -58,6 +58,24 @@ struct get_vdi_info {
uint8_t copy_policy;
};
+int write_btree_node(uint64_t id, void *mem, unsigned int len,
+ int copies, int copy_policy, int create)
+{
+ return sd_write_object(id, 0, mem, len, 0, 0, copies, copy_policy,
+ true, true);
+}
+
+int read_btree_node(uint64_t id, void **mem, unsigned int len)
+{
+ return sd_read_object(id, *mem, len, 0, true);
+}
+
+static inline bool is_data_obj_writeable(const struct sd_inode *inode,
+ int idx)
+{
+ return inode->vdi_id == INODE_GET_VDI(inode, idx);
+}
+
static void vdi_show_progress(uint64_t done, uint64_t total)
{
return show_progress(done, total, false);
@@ -82,7 +100,7 @@ static void stat_data_objs(const struct sd_inode *inode, uint64_t *my_objs,
nr = count_data_objs(inode);
for (int i = 0; i < nr; i++) {
- vdi_id = sd_inode_get_vdi(inode, i);
+ vdi_id = INODE_GET_VDI(inode, i);
if (vdi_id == 0)
continue;
if (vdi_id == vid) {
@@ -277,7 +295,7 @@ static int obj_info_filler(const char *sheep, uint64_t oid, struct sd_rsp *rsp,
if (info->success)
break;
info->success = true;
- vdi_id = sd_inode_get_vdi(inode, info->idx);
+ vdi_id = INODE_GET_VDI(inode, info->idx);
if (vdi_id) {
info->data_oid = vid_to_data_oid(vdi_id, info->idx);
return 1;
@@ -647,7 +665,7 @@ static int vdi_clone(int argc, char **argv)
size_t size;
vdi_show_progress(idx * SD_DATA_OBJ_SIZE, inode->vdi_size);
- vdi_id = sd_inode_get_vdi(inode, idx);
+ vdi_id = INODE_GET_VDI(inode, idx);
if (vdi_id) {
oid = vid_to_data_oid(vdi_id, idx);
ret = sd_read_object(oid, buf, SD_DATA_OBJ_SIZE, 0, true);
@@ -1207,7 +1225,7 @@ static int vdi_read(int argc, char **argv)
offset %= SD_DATA_OBJ_SIZE;
while (done < total) {
len = min(total - done, SD_DATA_OBJ_SIZE - offset);
- vdi_id = sd_inode_get_vdi(inode, idx);
+ vdi_id = INODE_GET_VDI(inode, idx);
if (vdi_id) {
oid = vid_to_data_oid(vdi_id, idx);
ret = sd_read_object(oid, buf, len, offset, false);
@@ -1283,7 +1301,7 @@ static int vdi_write(int argc, char **argv)
flags = 0;
len = min(total - done, SD_DATA_OBJ_SIZE - offset);
- vdi_id = sd_inode_get_vdi(inode, idx);
+ vdi_id = INODE_GET_VDI(inode, idx);
if (!vdi_id)
create = true;
else if (!is_data_obj_writeable(inode, idx)) {
@@ -1305,7 +1323,7 @@ static int vdi_write(int argc, char **argv)
total = done + len;
}
- sd_inode_set_vdi(inode, idx, inode->vdi_id);
+ INODE_SET_VDI(inode, idx, inode->vdi_id);
oid = vid_to_data_oid(inode->vdi_id, idx);
ret = sd_write_object(oid, old_oid, buf, len, offset, flags,
inode->nr_copies, inode->copy_policy,
@@ -1667,7 +1685,7 @@ int do_vdi_check(const struct sd_inode *inode)
max_idx = count_data_objs(inode);
vdi_show_progress(done, inode->vdi_size);
for (int idx = 0; idx < max_idx; idx++) {
- vid = sd_inode_get_vdi(inode, idx);
+ vid = INODE_GET_VDI(inode, idx);
if (vid) {
oid = vid_to_data_oid(vid, idx);
queue_vdi_check_work(inode, oid, &done, wq);
@@ -1822,8 +1840,8 @@ static int vdi_backup(int argc, char **argv)
}
for (idx = 0; idx < nr_objs; idx++) {
- uint32_t from_vid = sd_inode_get_vdi(from_inode, idx);
- uint32_t to_vid = sd_inode_get_vdi(to_inode, idx);
+ uint32_t from_vid = INODE_GET_VDI(from_inode, idx);
+ uint32_t to_vid = INODE_GET_VDI(to_inode, idx);
if (to_vid == 0 && from_vid == 0)
continue;
@@ -1875,7 +1893,7 @@ static int restore_obj(struct obj_backup *backup, uint32_t vid,
struct sd_inode *parent_inode)
{
int ret;
- uint32_t parent_vid = sd_inode_get_vdi(parent_inode, backup->idx);
+ uint32_t parent_vid = INODE_GET_VDI(parent_inode, backup->idx);
uint64_t parent_oid = 0;
if (parent_vid)
diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index d393460..30ff397 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -225,6 +225,10 @@ struct sd_inode {
uint32_t data_vdi_id[MAX_DATA_OBJS];
};
+typedef int (*write_node_fn)(uint64_t id, void *mem, unsigned int len,
+ int copies, int copy_policy, int create);
+typedef int (*read_node_fn)(uint64_t id, void **mem, unsigned int len);
+
struct sheepdog_vdi_attr {
char name[SD_MAX_VDI_LEN];
char tag[SD_MAX_VDI_TAG_LEN];
@@ -235,9 +239,11 @@ struct sheepdog_vdi_attr {
char value[SD_MAX_VDI_ATTR_VALUE_LEN];
};
-uint32_t sd_inode_get_vdi(const struct sd_inode *inode, int idx);
-void sd_inode_set_vdi(struct sd_inode *inode, int idx, uint32_t vdi_id);
-void sd_inode_copy_vdis(struct sd_inode *oldi, struct sd_inode *newi);
+extern uint32_t sd_inode_get_vdi(read_node_fn reader,
+ const struct sd_inode *inode, int idx);
+extern void sd_inode_set_vdi(write_node_fn writer, read_node_fn reader,
+ struct sd_inode *inode, int idx, uint32_t vdi_id);
+extern void sd_inode_copy_vdis(struct sd_inode *oldi, struct sd_inode *newi);
/* 64 bit FNV-1a non-zero initial basis */
#define FNV1A_64_INIT ((uint64_t) 0xcbf29ce484222325ULL)
@@ -326,12 +332,6 @@ static inline uint64_t hash_64(uint64_t val, unsigned int bits)
return sd_hash_64(val) >> (64 - bits);
}
-static inline bool is_data_obj_writeable(const struct sd_inode *inode,
- int idx)
-{
- return inode->vdi_id == sd_inode_get_vdi(inode, idx);
-}
-
static inline bool is_vdi_obj(uint64_t oid)
{
return !!(oid & VDI_BIT);
diff --git a/lib/sd_inode.c b/lib/sd_inode.c
index 65a472a..c03ca03 100644
--- a/lib/sd_inode.c
+++ b/lib/sd_inode.c
@@ -2,12 +2,14 @@
#include "sheepdog_proto.h"
-uint32_t sd_inode_get_vdi(const struct sd_inode *inode, int idx)
+uint32_t sd_inode_get_vdi(read_node_fn reader,
+ const struct sd_inode *inode, int idx)
{
return inode->data_vdi_id[idx];
}
-void sd_inode_set_vdi(struct sd_inode *inode, int idx, uint32_t vdi_id)
+void sd_inode_set_vdi(write_node_fn writer, read_node_fn reader,
+ struct sd_inode *inode, int idx, uint32_t vdi_id)
{
inode->data_vdi_id[idx] = vdi_id;
}
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index 615d912..e28e1b1 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -375,6 +375,15 @@ void objlist_cache_remove(uint64_t oid);
void put_request(struct request *req);
+int write_btree_node(uint64_t id, void *mem, unsigned int len,
+ int copies, int copy_policy, int create);
+int read_btree_node(uint64_t id, void **mem, unsigned int len);
+
+#define INODE_GET_VDI(inode, idx) (sd_inode_get_vdi(read_btree_node, \
+ inode, idx))
+#define INODE_SET_VDI(inode, idx, vdi_id) (sd_inode_set_vdi(write_btree_node,\
+ read_btree_node, inode, idx, vdi_id))
+
/* Operations */
const struct sd_op_template *get_sd_op(uint8_t opcode);
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 27227b7..dc3f975 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -22,6 +22,17 @@ struct vdi_state_entry {
static struct rb_root vdi_state_root = RB_ROOT;
static struct sd_lock vdi_state_lock = SD_LOCK_INITIALIZER;
+int write_btree_node(uint64_t id, void *mem, unsigned int len,
+ int copies, int copy_policy, int create)
+{
+ return write_object(id, mem, len, 0, create == 1);
+}
+
+int read_btree_node(uint64_t id, void **mem, unsigned int len)
+{
+ return read_object(id, *mem, len, 0);
+}
+
static int vdi_state_cmp(const struct vdi_state_entry *a,
const struct vdi_state_entry *b)
{
@@ -833,7 +844,7 @@ static void delete_one(struct work *work)
nr_objs = count_data_objs(inode);
for (nr_deleted = 0, i = 0; i < nr_objs; i++) {
uint64_t oid;
- uint32_t vid = sd_inode_get_vdi(inode, i);
+ uint32_t vid = INODE_GET_VDI(inode, i);
if (!vid)
continue;
diff --git a/sheepfs/volume.c b/sheepfs/volume.c
index ab16ada..c2df32a 100644
--- a/sheepfs/volume.c
+++ b/sheepfs/volume.c
@@ -64,6 +64,22 @@ struct vdi_inode {
static struct rb_root vdi_inode_tree = RB_ROOT;
static struct sd_lock vdi_inode_tree_lock = SD_LOCK_INITIALIZER;
+
+static int write_btree_node(uint64_t id, void *mem, unsigned int len,
+ int copies, int copy_policy, int create);
+static int read_btree_node(uint64_t id, void **mem, unsigned int len);
+
+#define INODE_GET_VDI(inode, idx) (sd_inode_get_vdi(\
+ read_btree_node, inode, idx))
+#define INODE_SET_VDI(inode, idx, vdi_id) (sd_inode_set_vdi(\
+ write_btree_node, read_btree_node, inode, idx, vdi_id))
+
+static inline bool is_data_obj_writeable(const struct sd_inode *inode,
+ int idx)
+{
+ return inode->vdi_id == INODE_GET_VDI(inode, idx);
+}
+
static int vdi_inode_cmp(const struct vdi_inode *a, const struct vdi_inode *b)
{
return intcmp(a->vid, b->vid);
@@ -129,7 +145,7 @@ static int volume_rw_object(char *buf, uint64_t oid, size_t size,
if (is_data_obj(oid)) {
idx = data_oid_to_idx(oid);
assert(vdi);
- vdi_id = sd_inode_get_vdi(vdi->inode, idx);
+ vdi_id = INODE_GET_VDI(vdi->inode, idx);
if (!vdi_id) {
/* if object doesn't exist, we'er done */
if (rw == VOLUME_READ) {
@@ -176,7 +192,7 @@ static int volume_rw_object(char *buf, uint64_t oid, size_t size,
}
if (create) {
- sd_inode_set_vdi(vdi->inode, idx, vid);
+ INODE_SET_VDI(vdi->inode, idx, vid);
/* writeback inode update */
if (volume_rw_object((char *)&vid, vid_to_vdi_oid(vid),
sizeof(vid),
@@ -231,6 +247,25 @@ static int volume_do_rw(const char *path, char *buf, size_t size,
return 0;
}
+int write_btree_node(uint64_t id, void *mem, unsigned int len,
+ int copies, int copy_policy, int create)
+{
+ int ret;
+ ret = volume_rw_object(mem, id, len, 0, VOLUME_WRITE);
+ if (ret == len)
+ return SD_RES_SUCCESS;
+ return ret;
+}
+
+int read_btree_node(uint64_t id, void **mem, unsigned int len)
+{
+ int ret;
+ ret = volume_rw_object(*mem, id, len, 0, VOLUME_READ);
+ if (ret == len)
+ return SD_RES_SUCCESS;
+ return ret;
+}
+
int volume_read(const char *path, char *buf, size_t size, off_t offset)
{
--
1.7.1
More information about the sheepdog
mailing list