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

Reply via email to