From 923b5637c16434ff3dab074a161dbcd1408694cc Mon Sep 17 00:00:00 2001 From: adilger Date: Wed, 29 May 2002 18:57:58 +0000 Subject: [PATCH] Update the journal callback code in patch-2.4.9-chaos14. While it is not necessary to update to this version of the journal callback if the older version is applied, this does the callbacks outside the journal semaphore and is the version likely to make it into ext3 proper. --- lustre/patches/patch-2.4.9-chaos14 | 82 +++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 27 deletions(-) diff --git a/lustre/patches/patch-2.4.9-chaos14 b/lustre/patches/patch-2.4.9-chaos14 index f2f6334..24b5628 100644 --- a/lustre/patches/patch-2.4.9-chaos14 +++ b/lustre/patches/patch-2.4.9-chaos14 @@ -89,28 +89,64 @@ diff -ru ../kernel-2.4.9/fs/jbd/commit.c ../kernel-2.4.9-lustre/fs/jbd/commit.c less likely to be woken up until all IOs have completed, and so we incur less scheduling load. */ -@@ -583,6 +583,21 @@ - journal_unlock_journal_head(descriptor); +@@ -566,8 +566,10 @@ + + jbd_debug(3, "JBD: commit phase 6\n"); + +- if (is_journal_aborted(journal)) ++ if (is_journal_aborted(journal)) { ++ unlock_journal(journal); + goto skip_commit; ++ } + + /* Done it all: now write the commit record. We should have + * cleaned up our previous buffers by now, so if we are in abort +@@ -577,9 +579,10 @@ + descriptor = journal_get_descriptor_buffer(journal); + if (!descriptor) { + __journal_abort_hard(journal); ++ unlock_journal(journal); + goto skip_commit; } - lock_journal(journal); +- + + /* AKPM: buglet - add `i' to tmp! */ + for (i = 0; i < jh2bh(descriptor)->b_size; i += 512) { + journal_header_t *tmp = +@@ -600,7 +603,6 @@ + put_bh(bh); /* One for getblk() */ + journal_unlock_journal_head(descriptor); + } +- lock_journal(journal); + + /* End of a transaction! Finally, we can do checkpoint + processing: any buffers committed as a result of this +@@ -609,6 +611,25 @@ + + skip_commit: + + /* Call any callbacks that had been registered for handles in this + * transaction. It is up to the callback to free any allocated + * memory. + */ -+ { ++ if (!list_empty(&commit_transaction->t_jcb)) { + struct list_head *p, *n; ++ int error = is_journal_aborted(journal); ++ + list_for_each_safe(p, n, &commit_transaction->t_jcb) { + struct journal_callback *jcb; + + jcb = list_entry(p, struct journal_callback, jcb_list); + list_del(p); -+ jcb->jcb_func(jcb); ++ jcb->jcb_func(jcb, error); + } + } ++ ++ lock_journal(journal); ++ + jbd_debug(3, "JBD: commit phase 7\n"); - /* End of a transaction! Finally, we can do checkpoint - processing: any buffers committed as a result of this + J_ASSERT(commit_transaction->t_sync_datalist == NULL); diff -ru ../kernel-2.4.9/fs/jbd/journal.c ../kernel-2.4.9-lustre/fs/jbd/journal.c --- ../kernel-2.4.9/fs/jbd/journal.c Wed Oct 31 17:51:37 2001 +++ ../kernel-2.4.9-lustre/fs/jbd/journal.c Mon May 13 14:23:05 2002 @@ -188,23 +224,25 @@ diff -ru ../kernel-2.4.9/fs/jbd/transaction.c ../kernel-2.4.9-lustre/fs/jbd/tran current->journal_info = handle; err = try_start_this_handle(journal, handle); -@@ -1344,6 +1353,27 @@ +@@ -1328,6 +1337,29 @@ #endif /* + * Register a callback function for this handle. The function will be + * called when the transaction that this handle is part of has been -+ * committed to disk. There is no guarantee of ordering between handles -+ * within a single transaction, nor between callbacks registered on the -+ * same handle. ++ * committed to disk with the original callback data struct and the ++ * error status of the journal as parameters. There is no guarantee of ++ * ordering between handles within a single transaction, nor between ++ * callbacks registered on the same handle. + * + * The caller is responsible for allocating the journal_callback struct. + * This is to allow the caller to add as much extra data to the callback + * as needed, but reduce the overhead of multiple allocations. The caller -+ * should use the journal_callback_size() function to reserve enough space -+ * for the JBD-private part of the callback struct. ++ * allocated struct must start with a struct journal_callback at offset 0, ++ * and has the caller-specific data afterwards. + */ -+void journal_callback_set(handle_t *handle, void (*func)(void *), void *cb_data) ++void journal_callback_set(handle_t *handle, void (*func)(void *, int), ++ void *cb_data) +{ + struct journal_callback *jcb = cb_data; + @@ -216,14 +254,13 @@ diff -ru ../kernel-2.4.9/fs/jbd/transaction.c ../kernel-2.4.9-lustre/fs/jbd/tran * All done for a particular handle. * * There is not much action needed here. We just return any remaining -@@ -1409,7 +1439,11 @@ +@@ -1409,7 +1439,10 @@ wake_up(&journal->j_wait_transaction_locked); } - /* + /* Move callbacks from the handle to the transaction. */ + list_splice(&handle->h_jcb, &transaction->t_jcb); -+ INIT_LIST_HEAD(&handle->h_jcb); + + /* * If the handle is marked SYNC, we need to set another commit @@ -249,10 +286,10 @@ diff -ru ../kernel-2.4.9/include/linux/jbd.h ../kernel-2.4.9-lustre/include/linu return bh->b_private; } -+#define HAVE_JOURNAL_CALLBACK ++#define HAVE_JOURNAL_CALLBACK_STATUS +struct journal_callback { + struct list_head jcb_list; -+ void (*jcb_func)(void *); ++ void (*jcb_func)(void *cb_data, int error); + /* user data goes here */ +}; + @@ -283,15 +320,6 @@ diff -ru ../kernel-2.4.9/include/linux/jbd.h ../kernel-2.4.9-lustre/include/linu }; -@@ -549,7 +566,7 @@ - #define JFS_FLUSHED 0x008 /* The journal superblock has been flushed */ - #define JFS_LOADED 0x010 /* The journal superblock has been loaded */ - --/* -+/* - * Function declarations for the journaling transaction and buffer - * management - */ @@ -647,6 +664,8 @@ extern int journal_try_to_free_buffers(journal_t *, struct page *, int); extern int journal_stop(handle_t *); -- 1.8.3.1