git » libjio » commit c66c022

jtrans_commit(): Do not unlink the journal file if rollback failed

author Alberto Bertogli
2009-07-16 15:10:51 UTC
committer Alberto Bertogli
2009-07-16 15:39:06 UTC
parent ed3a770ca76365e43be560ebbbabfa65dfcd0fe7

jtrans_commit(): Do not unlink the journal file if rollback failed

When the commit fails we attempt to rollback. If that fails too, we should
not unlink the journal file, because then there is no chance jfsck()
can recover from the possible corruption.

This patch makes jtrans_commit() keep that file, assuming the caller will
know that it should stop working on it and attempt to run jfsck().

Signed-off-by: Alberto Bertogli <albertito@blitiri.com.ar>

libjio/journal.c +6 -1
libjio/journal.h +1 -1
libjio/trans.c +6 -2

diff --git a/libjio/journal.c b/libjio/journal.c
index 51c63ea..80c6324 100644
--- a/libjio/journal.c
+++ b/libjio/journal.c
@@ -370,10 +370,15 @@ error:
 /** Free a journal operation.
  * NOTE: It can't assume the save completed successfuly, so we can call it
  * when journal_save() fails.  */
-int journal_free(struct journal_op *jop)
+int journal_free(struct journal_op *jop, int do_unlink)
 {
 	int rv;
 
+	if (!do_unlink) {
+		rv = 0;
+		goto exit;
+	}
+
 	rv = -1;
 
 	if (unlink(jop->name)) {
diff --git a/libjio/journal.h b/libjio/journal.h
index 5f7acd6..bdc1445 100644
--- a/libjio/journal.h
+++ b/libjio/journal.h
@@ -22,7 +22,7 @@ int journal_add_op(struct journal_op *jop, unsigned char *buf, size_t len,
 		off_t offset);
 void journal_pre_commit(struct journal_op *jop);
 int journal_commit(struct journal_op *jop);
-int journal_free(struct journal_op *jop);
+int journal_free(struct journal_op *jop, int do_unlink);
 
 int fill_trans(unsigned char *map, off_t len, struct jtrans *ts);
 
diff --git a/libjio/trans.c b/libjio/trans.c
index 989fb69..730f43c 100644
--- a/libjio/trans.c
+++ b/libjio/trans.c
@@ -334,7 +334,11 @@ unlink_exit:
 	 * will be marked as J_COMMITTED to indicate that the data was
 	 * effectively written to disk. */
 	if (jop) {
-		r = journal_free(jop);
+		/* Note we only unlink if we've written down the real data, or
+		 * at least rolled it back properly */
+		int data_is_safe = (ts->flags & J_COMMITTED) ||
+			(ts->flags & J_ROLLBACKED);
+		r = journal_free(jop, data_is_safe ? 1 : 0);
 		if (r != 0)
 			retval = -2;
 
@@ -580,7 +584,7 @@ int jsync(struct jfs *fs)
 	pthread_mutex_lock(&(fs->ltlock));
 	while (fs->ltrans != NULL) {
 		fiu_exit_on("jio/jsync/pre_unlink");
-		journal_free(fs->ltrans->jop);
+		journal_free(fs->ltrans->jop, 1);
 
 		ltmp = fs->ltrans->next;
 		free(fs->ltrans);