git » libjio » commit 0fac861

Lock regions before creating a new transaction in the journal

author Alberto Bertogli
2009-09-11 04:46:27 UTC
committer Alberto Bertogli
2009-09-11 04:46:27 UTC
parent f258da7c955cc0d932b6d0a5007a13792c6e5c8a

Lock regions before creating a new transaction in the journal

We must do it before creating a new transaction, so we know it's not
possible to have two overlapping transactions on disk at the same time
(unless using lingering transactions, in which case it makes no
difference).

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

libjio/trans.c +12 -8

diff --git a/libjio/trans.c b/libjio/trans.c
index 91970d7..e1747a8 100644
--- a/libjio/trans.c
+++ b/libjio/trans.c
@@ -258,12 +258,22 @@ ssize_t jtrans_commit(struct jtrans *ts)
 	if (ts->numops_w && (ts->flags & J_RDONLY))
 		goto exit;
 
+	/* Lock all the regions we're going to work with; otherwise there
+	 * could be another transaction trying to write the same spots and we
+	 * could end up with interleaved writes, that could break atomicity
+	 * warantees if we need to rollback.
+	 * Note we do this before creating a new transaction, so we know it's
+	 * not possible to have two overlapping transactions on disk at the
+	 * same time. */
+	if (lock_file_ranges(ts, F_LOCKW) != 0)
+		goto unlock_exit;
+
 	/* create and fill the transaction file only if we have at least one
 	 * write operation */
 	if (ts->numops_w) {
 		jop = journal_new(ts->fs, ts->flags);
 		if (jop == NULL)
-			goto exit;
+			goto unlock_exit;
 	}
 
 	for (op = ts->op; op != NULL; op = op->next) {
@@ -282,13 +292,6 @@ ssize_t jtrans_commit(struct jtrans *ts)
 
 	fiu_exit_on("jio/commit/tf_data");
 
-	/* lock all the regions we're going to work with; otherwise there
-	 * could be another transaction trying to write the same spots and we
-	 * could end up with interleaved writes, that could break atomicity
-	 * warantees if we need to rollback */
-	if (lock_file_ranges(ts, F_LOCKW) != 0)
-		goto unlink_exit;
-
 	if (!(ts->flags & J_NOROLLBACK)) {
 		for (op = ts->op; op != NULL; op = op->next) {
 			if (op->direction == D_READ)
@@ -433,6 +436,7 @@ unlink_exit:
 		jop = NULL;
 	}
 
+unlock_exit:
 	/* always unlock everything at the end; otherwise we could have
 	 * half-overlapping transactions applying simultaneously, and if
 	 * anything goes wrong it would be possible to break consistency */