B-tree is just a abstract structure so it need to call callback-function to read and write nodes.
Signed-off-by: Robin Dong <[email protected]> --- 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 -- sheepdog mailing list [email protected] http://lists.wpkg.org/mailman/listinfo/sheepdog
