Current journal implementation doesn't consider such a case: 1. make new journal for new object creation 2. actual creation of the object 3. delete object 4. crash
After such a sequence, the journaling mechanism recovers the deleted object. This behavior isn't valid. This patch implements the new journal flag: JF_DELETE_OBJ. If the journaling mechanism finds an entry with this flag during recovery process, it deletes an corresponding object. Signed-off-by: Hitoshi Mitake <[email protected]> --- sheep/journal.c | 29 +++++++++++++++++++++++++++-- sheep/plain_store.c | 3 +++ sheep/sheep_priv.h | 1 + 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/sheep/journal.c b/sheep/journal.c index be1a6b7..aea0115 100644 --- a/sheep/journal.c +++ b/sheep/journal.c @@ -53,6 +53,7 @@ struct journal_descriptor { #define JF_STORE 0 #define JF_EPOCH 1 #define JF_CONFIG 2 +#define JF_DELETE_OBJ 3 static const char *jfile_name[2] = { "journal_file0", "journal_file1", }; static int jfile_fds[2]; @@ -140,10 +141,14 @@ static void journal_get_path(struct journal_descriptor *jd, char *path) { switch (jd->flag) { case JF_STORE: + case JF_DELETE_OBJ: snprintf(path, PATH_MAX, "%s/%016"PRIx64, get_object_path(jd->oid), jd->oid); - sd_iprintf("%s, size %"PRIu64", off %"PRIu64", %d", - path, jd->size, jd->offset, jd->create); + if (jd->flag == JF_STORE) + sd_iprintf("%s, size %"PRIu64", off %"PRIu64", %d", + path, jd->size, jd->offset, jd->create); + else + sd_iprintf("%s (delete)", path); break; case JF_EPOCH: snprintf(path, PATH_MAX, "%s/%08"PRIu32, epoch_path, jd->epoch); @@ -154,6 +159,9 @@ static void journal_get_path(struct journal_descriptor *jd, char *path) snprintf(path, PATH_MAX, "%s", config_path); sd_iprintf("%s, size %"PRIu64, path, jd->size); break; + default: + panic("unknown type of journal flag: %d", jd->flag); + break; } } @@ -165,6 +173,12 @@ static int replay_journal_entry(struct journal_descriptor *jd) void *buf = NULL; char *p = (char *)jd; + if (jd->flag == JF_DELETE_OBJ) { + journal_get_path(jd, path); + unlink(path); + return; + } + if (jd->create) flags |= O_CREAT; @@ -453,3 +467,14 @@ int journal_write_config(const char *buf, size_t size) }; return journal_file_write(&jd, buf); } + +int journal_delete_object(uint64_t oid) +{ + struct journal_descriptor jd = { + .magic = JOURNAL_DESC_MAGIC, + .flag = JF_DELETE_OBJ, + .size = 0, + }; + jd.oid = oid; + return journal_file_write(&jd, NULL); +} diff --git a/sheep/plain_store.c b/sheep/plain_store.c index b5bb395..38c5c62 100644 --- a/sheep/plain_store.c +++ b/sheep/plain_store.c @@ -452,6 +452,9 @@ int default_remove_object(uint64_t oid) { char path[PATH_MAX]; + if (uatomic_is_true(&sys->use_journal)) + journal_delete_object(oid); + get_obj_path(oid, path); if (unlink(path) < 0) { diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h index a447387..9b3a7ac 100644 --- a/sheep/sheep_priv.h +++ b/sheep/sheep_priv.h @@ -407,6 +407,7 @@ int journal_write_store(uint64_t oid, const char *buf, size_t size, off_t, bool); int journal_write_epoch(const char *buf, size_t size, uint32_t epoch); int journal_write_config(const char *buf, size_t size); +int journal_delete_object(uint64_t oid); /* md.c */ void md_add_disk(char *path); -- 1.7.5.1 -- sheepdog mailing list [email protected] http://lists.wpkg.org/mailman/listinfo/sheepdog
