[sheepdog] [PATCH 2/2] farm: recover object from omap when trunk is not found

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Tue Aug 7 15:11:28 CEST 2012


While trunk_file_write_recovery is ongoing in the worker thread,
retrieve_object_from_snap will fail because the requested trunk object
are not created until all stale objects are removed from the working
directory.

This patch tries to use omap in trunk.c when sheep fails to read the
trunk object.

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 sheep/farm/farm.c  |   15 +++++++++++++++
 sheep/farm/farm.h  |    1 +
 sheep/farm/trunk.c |   39 +++++++++++++++++++++++++++++++++++++--
 3 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/sheep/farm/farm.c b/sheep/farm/farm.c
index 7eeae9a..128beb0 100644
--- a/sheep/farm/farm.c
+++ b/sheep/farm/farm.c
@@ -478,6 +478,21 @@ static int farm_read(uint64_t oid, struct siocb *iocb)
 					break;
 			}
 		}
+
+		/* retrieve_object_from_snap fails while farm_end_recover is
+		 * ongoing because the trunk object is not created yet.
+		 * Let's get the sha1 value from omap in that case.*/
+		if (!buffer) {
+			unsigned char *sha1;
+			struct sha1_file_hdr h;
+
+			sha1 = get_sha1_from_omap(oid);
+			if (sha1)
+				buffer = sha1_file_read(sha1, &h);
+
+			dprintf("retrieve object %"PRIx64" with omap, %s\n",
+				oid, buffer ? "succeed" : "fail");
+		}
 		if (!buffer)
 			return SD_RES_NO_OBJ;
 		memcpy(iocb->buf, buffer, iocb->length);
diff --git a/sheep/farm/farm.h b/sheep/farm/farm.h
index 27e65cd..9d29e53 100644
--- a/sheep/farm/farm.h
+++ b/sheep/farm/farm.h
@@ -66,6 +66,7 @@ extern int trunk_update_entry(uint64_t oid);
 extern void trunk_reset(void);
 extern void trunk_put_entry(uint64_t oid);
 extern void trunk_get_entry(uint64_t oid);
+extern unsigned char *get_sha1_from_omap(uint64_t oid);
 
 /* snap.c */
 extern int snap_init(void);
diff --git a/sheep/farm/trunk.c b/sheep/farm/trunk.c
index 8a53f9f..db5286f 100644
--- a/sheep/farm/trunk.c
+++ b/sheep/farm/trunk.c
@@ -45,7 +45,8 @@ struct omap_entry {
 	struct rb_node node;
 };
 
-struct rb_root omap_tree;
+static struct rb_root omap_tree;
+static pthread_mutex_t omap_tree_lock = PTHREAD_MUTEX_INITIALIZER;
 
 static inline int trunk_entry_is_dirty(struct trunk_entry_incore *entry)
 {
@@ -196,6 +197,8 @@ static struct omap_entry *omap_tree_rb_insert(struct rb_root *root,
 	struct rb_node *parent = NULL;
 	struct omap_entry *entry;
 
+	pthread_mutex_lock(&omap_tree_lock);
+
 	while (*p) {
 		parent = *p;
 		entry = rb_entry(parent, struct omap_entry, node);
@@ -204,12 +207,15 @@ static struct omap_entry *omap_tree_rb_insert(struct rb_root *root,
 			p = &(*p)->rb_left;
 		else if (new->oid > entry->oid)
 			p = &(*p)->rb_right;
-		else
+		else {
+			pthread_mutex_unlock(&omap_tree_lock);
 			return entry; /* already has this entry */
+		}
 	}
 	rb_link_node(&new->node, parent, p);
 	rb_insert_color(&new->node, root);
 
+	pthread_mutex_unlock(&omap_tree_lock);
 	return NULL; /* insert successfully */
 }
 
@@ -238,6 +244,35 @@ static unsigned char *omap_tree_insert(uint64_t oid, unsigned char *sha1)
 	return NULL;
 }
 
+unsigned char *get_sha1_from_omap(uint64_t oid)
+{
+	static unsigned char sha1[SHA1_LEN];
+	struct rb_node **p;
+	struct rb_node *parent = NULL;
+	struct omap_entry *entry;
+
+	pthread_mutex_lock(&omap_tree_lock);
+
+	p = &omap_tree.rb_node;
+	while (*p) {
+		parent = *p;
+		entry = rb_entry(parent, struct omap_entry, node);
+
+		if (oid < entry->oid)
+			p = &(*p)->rb_left;
+		else if (oid > entry->oid)
+			p = &(*p)->rb_right;
+		else {
+			memcpy(sha1, entry->sha1, SHA1_LEN);
+			pthread_mutex_unlock(&omap_tree_lock);
+			return sha1;
+		}
+	}
+
+	pthread_mutex_unlock(&omap_tree_lock);
+	return NULL; /* not found */
+}
+
 static int oid_stale(uint64_t oid)
 {
 	int i, nr_copies;
-- 
1.7.2.5




More information about the sheepdog mailing list