From: Robin Dong <san...@taobao.com> get_vnode_info() should be called only once in for_each_object_in_wd() (in the main thread) and the result should be passed to thread_process_path() as a pthread argument. This avoids lots of calls to get_vnode_info() and is necessary to pass our thread checker of the sheepdog tracer.
Signed-off-by: Robin Dong <san...@taobao.com> Signed-off-by: Liu Yuan <namei.u...@gmail.com> --- sheep/md.c | 33 +++++++++++++++++++++++---------- sheep/migrate.c | 1 + sheep/plain_store.c | 17 +++++++++-------- sheep/sheep_priv.h | 5 +++-- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/sheep/md.c b/sheep/md.c index e8f1d90..5c8deda 100644 --- a/sheep/md.c +++ b/sheep/md.c @@ -143,7 +143,8 @@ static struct disk *path_to_disk(const char *path) } static int get_total_object_size(uint64_t oid, const char *wd, uint32_t epoch, - uint8_t ec_index, void *total) + uint8_t ec_index, struct vnode_info *vinfo, + void *total) { uint64_t *t = total; struct stat s; @@ -175,8 +176,10 @@ static int64_t find_string_integer(const char *str, const char *delimiter) /* If cleanup is true, temporary objects will be removed */ static int for_each_object_in_path(const char *path, int (*func)(uint64_t, const char *, uint32_t, - uint8_t, void *), - bool cleanup, void *arg) + uint8_t, struct vnode_info *, + void *), + bool cleanup, struct vnode_info *vinfo, + void *arg) { DIR *dir; struct dirent *d; @@ -223,7 +226,7 @@ static int for_each_object_in_path(const char *path, continue; } - ret = func(oid, path, epoch, ec_index, arg); + ret = func(oid, path, epoch, ec_index, vinfo, arg); if (ret != SD_RES_SUCCESS) break; } @@ -244,7 +247,8 @@ static uint64_t get_path_free_size(const char *path, uint64_t *used) if (!used) goto out; - if (for_each_object_in_path(path, get_total_object_size, false, used) + if (for_each_object_in_path(path, get_total_object_size, false, + NULL, used) != SD_RES_SUCCESS) return 0; out: @@ -373,7 +377,9 @@ const char *md_get_object_dir(uint64_t oid) struct process_path_arg { const char *path; - int (*func)(uint64_t oid, const char *, uint32_t, uint8_t, void *arg); + struct vnode_info *vinfo; + int (*func)(uint64_t oid, const char *, uint32_t, uint8_t, + struct vnode_info *, void *arg); bool cleanup; void *opaque; int result; @@ -385,7 +391,7 @@ static void *thread_process_path(void *arg) struct process_path_arg *parg = (struct process_path_arg *)arg; ret = for_each_object_in_path(parg->path, parg->func, parg->cleanup, - parg->opaque); + parg->vinfo, parg->opaque); if (ret != SD_RES_SUCCESS) parg->result = ret; @@ -394,12 +400,13 @@ static void *thread_process_path(void *arg) main_fn int for_each_object_in_wd(int (*func)(uint64_t oid, const char *path, uint32_t epoch, uint8_t ec_index, - void *arg), + struct vnode_info *vinfo, void *arg), bool cleanup, void *arg) { int ret = SD_RES_SUCCESS; const struct disk *disk; struct process_path_arg *thread_args, *path_arg; + struct vnode_info *vinfo; void *ret_arg; pthread_t *thread_array; int nr_thread = 0, idx = 0; @@ -413,8 +420,11 @@ main_fn int for_each_object_in_wd(int (*func)(uint64_t oid, const char *path, thread_args = xmalloc(nr_thread * sizeof(struct process_path_arg)); thread_array = xmalloc(nr_thread * sizeof(pthread_t)); + vinfo = get_vnode_info(); + rb_for_each_entry(disk, &md.root, rb) { thread_args[idx].path = disk->path; + thread_args[idx].vinfo = vinfo; thread_args[idx].func = func; thread_args[idx].cleanup = cleanup; thread_args[idx].opaque = arg; @@ -447,6 +457,8 @@ main_fn int for_each_object_in_wd(int (*func)(uint64_t oid, const char *path, sd_strerror(path_arg->result)); } } + + put_vnode_info(vinfo); sd_rw_unlock(&md.lock); free(thread_args); @@ -455,7 +467,8 @@ main_fn int for_each_object_in_wd(int (*func)(uint64_t oid, const char *path, } int for_each_object_in_stale(int (*func)(uint64_t oid, const char *path, - uint32_t epoch, uint8_t, void *arg), + uint32_t epoch, uint8_t, + struct vnode_info *, void *arg), void *arg) { int ret = SD_RES_SUCCESS; @@ -465,7 +478,7 @@ int for_each_object_in_stale(int (*func)(uint64_t oid, const char *path, sd_read_lock(&md.lock); rb_for_each_entry(disk, &md.root, rb) { snprintf(path, sizeof(path), "%s/.stale", disk->path); - ret = for_each_object_in_path(path, func, false, arg); + ret = for_each_object_in_path(path, func, false, NULL, arg); if (ret != SD_RES_SUCCESS) break; } diff --git a/sheep/migrate.c b/sheep/migrate.c index 0d69fa1..fcffc1e 100644 --- a/sheep/migrate.c +++ b/sheep/migrate.c @@ -429,6 +429,7 @@ static int migrate_from_v2_to_v3(void) static int convert_ecidx_xattr2path(uint64_t oid, const char *wd, uint32_t epoch, uint8_t ec_index, + struct vnode_info *info, void *arg) { int ret = 0; diff --git a/sheep/plain_store.c b/sheep/plain_store.c index 9338c86..4388133 100644 --- a/sheep/plain_store.c +++ b/sheep/plain_store.c @@ -233,6 +233,7 @@ out: static int init_objlist_and_vdi_bitmap(uint64_t oid, const char *wd, uint32_t epoch, uint8_t ec_index, + struct vnode_info *vinfo, void *arg) { int ret; @@ -445,14 +446,12 @@ out: * node(index gets changed even it has some other copy belongs to it) because * of hash ring changes, we consider it stale. */ -static bool oid_stale(uint64_t oid, int ec_index) +static bool oid_stale(uint64_t oid, int ec_index, struct vnode_info *vinfo) { uint32_t i, nr_copies; - struct vnode_info *vinfo; const struct sd_vnode *v; bool ret = true; const struct sd_vnode *obj_vnodes[SD_MAX_COPIES]; - vinfo = get_vnode_info(); nr_copies = get_obj_copy_number(oid, vinfo->nr_zones); oid_to_vnodes(oid, &vinfo->vroot, nr_copies, obj_vnodes); @@ -469,12 +468,12 @@ static bool oid_stale(uint64_t oid, int ec_index) } } - put_vnode_info(vinfo); return ret; } static int move_object_to_stale_dir(uint64_t oid, const char *wd, - uint32_t epoch, uint8_t ec_index, void *arg) + uint32_t epoch, uint8_t ec_index, + struct vnode_info *vinfo, void *arg) { char path[PATH_MAX], stale_path[PATH_MAX]; uint32_t tgt_epoch = *(uint32_t *)arg; @@ -504,10 +503,12 @@ static int move_object_to_stale_dir(uint64_t oid, const char *wd, } static int check_stale_objects(uint64_t oid, const char *wd, uint32_t epoch, - uint8_t ec_index, void *arg) + uint8_t ec_index, struct vnode_info *vinfo, + void *arg) { - if (oid_stale(oid, ec_index)) - return move_object_to_stale_dir(oid, wd, 0, ec_index, arg); + if (oid_stale(oid, ec_index, vinfo)) + return move_object_to_stale_dir(oid, wd, 0, ec_index, + NULL, arg); return SD_RES_SUCCESS; } diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h index 4f44b16..46f8655 100644 --- a/sheep/sheep_priv.h +++ b/sheep/sheep_priv.h @@ -241,10 +241,11 @@ int default_remove_object(uint64_t oid, uint8_t ec_index); int default_get_hash(uint64_t oid, uint32_t epoch, uint8_t *sha1); int default_purge_obj(void); int for_each_object_in_wd(int (*func)(uint64_t, const char *, uint32_t, - uint8_t, void *), + uint8_t, struct vnode_info *, void *), bool, void *); int for_each_object_in_stale(int (*func)(uint64_t oid, const char *path, - uint32_t epoch, uint8_t, void *arg), + uint32_t epoch, uint8_t, + struct vnode_info *, void *arg), void *arg); int for_each_obj_path(int (*func)(const char *path)); size_t get_store_objsize(uint64_t oid); -- 1.8.3.2 -- sheepdog mailing list sheepdog@lists.wpkg.org http://lists.wpkg.org/mailman/listinfo/sheepdog