[sheepdog] [PATCH stable-0.8 2/2] sheep/md: called get_vnode_info() only once in for_each_object_in_wd()

Hitoshi Mitake mitake.hitoshi at lab.ntt.co.jp
Wed Aug 13 11:05:28 CEST 2014


From: Robin Dong <sanbai at 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 <sanbai at taobao.com>
Signed-off-by: Liu Yuan <namei.unix at 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




More information about the sheepdog mailing list