[Sheepdog] [PATCH] sheep: abstract out link operation for storage

Liu Yuan namei.unix at gmail.com
Fri Dec 16 10:48:52 CET 2011


From: Liu Yuan <tailai.ly at taobao.com>

Currently if we recover the object from local old epoch store, we simply do
a hardlink to the old object. Since this operation holds some assumption about
underlying object store layout, we'd abstract it out.

Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
 sheep/sheep_priv.h   |    2 ++
 sheep/simple_store.c |   21 ++++++++++++++++++++-
 sheep/store.c        |   15 ++++++---------
 3 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index a448157..9890058 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -172,7 +172,9 @@ struct store_driver {
 	int (*write)(uint64_t oid, struct siocb *);
 	int (*read)(uint64_t oid, struct siocb *);
 	int (*close)(uint64_t oid, struct siocb *);
+	/* Operations in recovery */
 	int (*get_objlist)(struct siocb *);
+	int (*link)(uint64_t oid, struct siocb *, int tgt_epoch);
 };
 
 extern void register_store_driver(struct store_driver *);
diff --git a/sheep/simple_store.c b/sheep/simple_store.c
index 21b5404..3bc3f47 100644
--- a/sheep/simple_store.c
+++ b/sheep/simple_store.c
@@ -179,6 +179,24 @@ out:
 	return ret;
 }
 
+static int simple_store_link(uint64_t oid, struct siocb *iocb, int tgt_epoch)
+{
+       char old[PATH_MAX], new[PATH_MAX];
+
+       snprintf(old, sizeof(old), "%s%08u/%016" PRIx64, obj_path,
+                tgt_epoch, oid);
+       snprintf(new, sizeof(new), "%s%08u/%016" PRIx64, obj_path,
+                iocb->epoch, oid);
+       dprintf("link from %s to %s\n", old, new);
+       if (link(old, new) == 0)
+               return SD_RES_SUCCESS;
+
+       if (errno == ENOENT)
+               return SD_RES_NO_OBJ;
+
+       return SD_RES_EIO;
+}
+
 struct store_driver store = {
 	.driver_name = "simple",
 	.init = simple_store_init,
@@ -186,7 +204,8 @@ struct store_driver store = {
 	.write = simple_store_write,
 	.read = simple_store_read,
 	.close = simple_store_close,
-	.get_objlist = simple_store_get_objlist
+	.get_objlist = simple_store_get_objlist,
+	.link = simple_store_link,
 };
 
 void register_store_driver(struct store_driver *driver)
diff --git a/sheep/store.c b/sheep/store.c
index 43089ce..3d99b1c 100644
--- a/sheep/store.c
+++ b/sheep/store.c
@@ -1192,17 +1192,14 @@ next:
 	e = old_entry + tgt_idx;
 
 	if (is_myself(e->addr, e->port)) {
-		char old[PATH_MAX], new[PATH_MAX];
+		struct siocb iocb = { 0 };
 
-		snprintf(old, sizeof(old), "%s%08u/%016" PRIx64, obj_path,
-			 tgt_epoch, oid);
-		snprintf(new, sizeof(new), "%s%08u/%016" PRIx64, obj_path,
-			 epoch, oid);
-		dprintf("link from %s to %s\n", old, new);
-		if (link(old, new) == 0)
+		iocb.epoch = epoch;
+		ret = store.link(oid, &iocb, tgt_epoch);
+		if (ret == SD_RES_SUCCESS)
 			goto out;
 
-		if (errno == ENOENT) {
+		if (ret == SD_RES_NO_OBJ) {
 			next_nr = epoch_log_read(tgt_epoch - 1, buf, buf_len);
 			if (next_nr <= 0) {
 				eprintf("no previous epoch: %"PRIu32"\n", tgt_epoch - 1);
@@ -1216,7 +1213,7 @@ next:
 			goto not_found;
 		}
 
-		eprintf("cannot recover from local %s to %s\n", old, new);
+		eprintf("Cannot recover from local store for %"PRIx64"\n", oid);
 		goto err;
 	}
 
-- 
1.7.8.rc3




More information about the sheepdog mailing list