On Sat, Nov 16, 2013 at 10:57:35PM +0800, Robin Dong wrote:
> Add framework about traverse of B-tree for vdi_list() and vdi_check()
> 
> Signed-off-by: Robin Dong <[email protected]>
> ---
>  dog/vdi.c                |  105 +++++++++++++++++++++++++++++++++++++--------
>  include/sheepdog_proto.h |   10 ++++
>  lib/sd_inode.c           |   56 +++++++++++++++++++-----
>  3 files changed, 140 insertions(+), 31 deletions(-)
> 
> diff --git a/dog/vdi.c b/dog/vdi.c
> index 3042577..6e2e94d 100644
> --- a/dog/vdi.c
> +++ b/dog/vdi.c
> @@ -85,14 +85,37 @@ static void vdi_show_progress(uint64_t done, uint64_t 
> total)
>       return show_progress(done, total, false);
>  }
>  
> -/*
> - * Get the number of objects.
> - *
> - * 'my_objs' means the number objects which belongs to this vdi.  'cow_objs'
> - * means the number of the other objects.
> - */
> -static void stat_data_objs(const struct sd_inode *inode, uint64_t *my_objs,
> -                        uint64_t *cow_objs)
> +struct stat_arg {
> +     uint64_t *my;
> +     uint64_t *cow;
> +     uint32_t vid;
> +};
> +
> +static void stat_cb(void *data, enum btree_node_type type, void *arg)
> +{
> +     struct sd_extent *ext;
> +     struct stat_arg *sarg = arg;
> +     uint64_t *my = sarg->my;
> +     uint64_t *cow = sarg->cow;
> +
> +     if (type == BTREE_EXT) {
> +             ext = (struct sd_extent *)data;
> +             if (ext->vdi_id == sarg->vid)
> +                     (*my)++;
> +             else if (ext->vdi_id != 0)
> +                     (*cow)++;
> +     }
> +}
> +
> +static void stat_data_objs_btree(const struct sd_inode *inode,
> +                              uint64_t *my_objs, uint64_t *cow_objs)
> +{
> +     struct stat_arg arg = {my_objs, cow_objs, inode->vdi_id};
> +     traverse_btree(dog_bnode_reader, inode, stat_cb, &arg);
> +}
> +
> +static void stat_data_objs_array(const struct sd_inode *inode,
> +                              uint64_t *my_objs, uint64_t *cow_objs)
>  {
>       int nr;
>       uint64_t my, cow, *p;
> @@ -141,12 +164,27 @@ static void stat_data_objs(const struct sd_inode 
> *inode, uint64_t *my_objs,
>       *cow_objs = cow;
>  }
>  
> +/*
> + * Get the number of objects.
> + *
> + * 'my_objs' means the number objects which belongs to this vdi.  'cow_objs'
> + * means the number of the other objects.
> + */
> +static void stat_data_objs(const struct sd_inode *inode, uint64_t *my_objs,
> +                        uint64_t *cow_objs)
> +{
> +     if (inode->store_policy == 0)
> +             stat_data_objs_array(inode, my_objs, cow_objs);
> +     else
> +             stat_data_objs_btree(inode, my_objs, cow_objs);
> +}
> +
>  static void print_vdi_list(uint32_t vid, const char *name, const char *tag,
>                          uint32_t snapid, uint32_t flags,
>                          const struct sd_inode *i, void *data)
>  {
>       bool is_clone = false;
> -     uint64_t my_objs, cow_objs;
> +     uint64_t my_objs = 0, cow_objs = 0;
>       time_t ti;
>       struct tm tm;
>       char dbuf[128];
> @@ -1702,6 +1740,29 @@ static void queue_vdi_check_work(const struct sd_inode 
> *inode, uint64_t oid,
>       }
>  }
>  
> +struct check_arg {
> +     const struct sd_inode *inode;
> +     uint64_t *done;
> +     struct work_queue *wq;
> +};
> +
> +static void check_cb(void *data, enum btree_node_type type, void *arg)
> +{
> +     struct sd_extent *ext;
> +     struct check_arg *carg = arg;
> +     uint64_t oid;
> +
> +     if (type == BTREE_EXT) {
> +             ext = (struct sd_extent *)data;
> +             if (ext->vdi_id) {
> +                     oid = vid_to_data_oid(ext->vdi_id, ext->idx);
> +                     *(carg->done) = (uint64_t)ext->idx * SD_DATA_OBJ_SIZE;
> +                     vdi_show_progress(*(carg->done), carg->inode->vdi_size);
> +                     queue_vdi_check_work(carg->inode, oid, NULL, carg->wq);
> +             }
> +     }
> +}
> +
>  int do_vdi_check(const struct sd_inode *inode)
>  {
>       uint32_t max_idx;
> @@ -1720,17 +1781,23 @@ int do_vdi_check(const struct sd_inode *inode)
>  
>       queue_vdi_check_work(inode, vid_to_vdi_oid(inode->vdi_id), NULL, wq);
>  
> -     max_idx = count_data_objs(inode);
> -     vdi_show_progress(done, inode->vdi_size);
> -     for (uint32_t idx = 0; idx < max_idx; idx++) {
> -             vid = INODE_GET_VID(inode, idx);
> -             if (vid) {
> -                     oid = vid_to_data_oid(vid, idx);
> -                     queue_vdi_check_work(inode, oid, &done, wq);
> -             } else {
> -                     done += SD_DATA_OBJ_SIZE;
> -                     vdi_show_progress(done, inode->vdi_size);
> +     if (inode->store_policy == 0) {
> +             max_idx = count_data_objs(inode);
> +             vdi_show_progress(done, inode->vdi_size);
> +             for (uint32_t idx = 0; idx < max_idx; idx++) {
> +                     vid = INODE_GET_VID(inode, idx);
> +                     if (vid) {
> +                             oid = vid_to_data_oid(vid, idx);
> +                             queue_vdi_check_work(inode, oid, &done, wq);
> +                     } else {
> +                             done += SD_DATA_OBJ_SIZE;
> +                             vdi_show_progress(done, inode->vdi_size);
> +                     }
>               }
> +     } else {
> +             struct check_arg arg = {inode, &done, wq};
> +             traverse_btree(dog_bnode_reader, inode, check_cb, &arg);
> +             vdi_show_progress(inode->vdi_size, inode->vdi_size);
>       }
>  
>       work_queue_wait(wq);
> diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
> index 72a1e3a..56a606e 100644
> --- a/include/sheepdog_proto.h
> +++ b/include/sheepdog_proto.h
> @@ -252,6 +252,12 @@ struct sd_extent_header {
>       uint32_t entries;
>  };
>  
> +enum btree_node_type {
> +     BTREE_HEAD = 1,
> +     BTREE_EXT,
> +     BTREE_IDX,
> +};
> +
>  typedef int (*write_node_fn)(uint64_t id, void *mem, unsigned int len,
>                               uint64_t offset, uint32_t flags, int copies,
>                               int copy_policy, bool create, bool direct);
> @@ -280,6 +286,10 @@ extern int sd_inode_write_vid(write_node_fn writer, 
> struct sd_inode *inode,
>  extern uint32_t sd_inode_get_meta_size(struct sd_inode *inode, size_t size);
>  extern void sd_inode_copy_vdis(struct sd_inode *oldi, struct sd_inode *newi);
>  
> +typedef void (*btree_cb_fn)(void *data, enum btree_node_type type, void 
> *arg);
> +extern void traverse_btree(read_node_fn reader, const struct sd_inode *inode,
> +                        btree_cb_fn fn, void *arg);
> +
>  /* 64 bit FNV-1a non-zero initial basis */
>  #define FNV1A_64_INIT ((uint64_t) 0xcbf29ce484222325ULL)
>  #define FNV_64_PRIME ((uint64_t) 0x100000001b3ULL)
> diff --git a/lib/sd_inode.c b/lib/sd_inode.c
> index be9f904..c76a1bc 100644
> --- a/lib/sd_inode.c
> +++ b/lib/sd_inode.c
> @@ -132,25 +132,24 @@ static int index_comp(void *a, void *b)
>               return 0;
>  }
>  
> -/* dump the information of B-tree */
> -static void dump_btree(read_node_fn reader, struct sd_inode *inode)
> +/* traverse the whole btree that include all the inode->data_vdi_id, bnode,
> + * data objects and call btree_cb_fn() */

Our checkpatch complains at this comment style.

Thanks
Yuan
-- 
sheepdog mailing list
[email protected]
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to