From: girish Date: Fri, 29 May 2009 12:32:12 +0000 (+0000) Subject: b=16893 X-Git-Tag: v1_8_2_01~1^2~366 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=aea217d5fc05683fd8f481855d5f3c841e7ec48a;p=fs%2Flustre-release.git b=16893 i=adilger i=johann jbd2 kernel patch needed for ext4 port to rhel5 --- diff --git a/lustre/kernel_patches/patches/jbd2-jcberr-2.6-rhel5.patch b/lustre/kernel_patches/patches/jbd2-jcberr-2.6-rhel5.patch new file mode 100644 index 0000000..476e06f --- /dev/null +++ b/lustre/kernel_patches/patches/jbd2-jcberr-2.6-rhel5.patch @@ -0,0 +1,221 @@ +Index: linux-2.6.18-128.1.6/include/linux/jbd2.h +=================================================================== +--- linux-2.6.18-128.1.6.orig/include/linux/jbd2.h 2009-04-15 08:35:28.000000000 +0530 ++++ linux-2.6.18-128.1.6/include/linux/jbd2.h 2009-05-28 15:10:18.000000000 +0530 +@@ -381,6 +381,27 @@ + bit_spin_unlock(BH_JournalHead, &bh->b_state); + } + ++#define HAVE_JOURNAL_CALLBACK_STATUS ++/** ++ * struct journal_callback - Base structure for callback information. ++ * @jcb_list: list information for other callbacks attached to the same handle. ++ * @jcb_func: Function to call with this callback structure. ++ * ++ * This struct is a 'seed' structure for a using with your own callback ++ * structs. If you are using callbacks you must allocate one of these ++ * or another struct of your own definition which has this struct ++ * as it's first element and pass it to journal_callback_set(). ++ * ++ * This is used internally by jbd2 to maintain callback information. ++ * ++ * See journal_callback_set for more information. ++ **/ ++struct journal_callback { ++ struct list_head jcb_list; /* t_jcb_lock */ ++ void (*jcb_func)(struct journal_callback *jcb, int error); ++ /* user data goes here */ ++}; ++ + struct jbd2_revoke_table_s; + + /** +@@ -389,6 +410,7 @@ + * @h_transaction: Which compound transaction is this update a part of? + * @h_buffer_credits: Number of remaining buffers we are allowed to dirty. + * @h_ref: Reference count on this handle ++ * @h_jcb: List of application registered callbacks for this handle. + * @h_err: Field for caller's use to track errors through large fs operations + * @h_sync: flag for sync-on-close + * @h_jdata: flag to force data journaling +@@ -414,6 +436,13 @@ + /* operations */ + int h_err; + ++ /* ++ * List of application registered callbacks for this handle. The ++ * function(s) will be called after the transaction that this handle is ++ * part of has been committed to disk. [t_jcb_lock] ++ */ ++ struct list_head h_jcb; ++ + /* Flags [no locking] */ + unsigned int h_sync: 1; /* sync-on-close */ + unsigned int h_jdata: 1; /* force data journaling */ +@@ -469,6 +498,8 @@ + * j_state_lock + * ->j_list_lock (journal_unmap_buffer) + * ++ * t_handle_lock ++ * ->t_jcb_lock + */ + + struct transaction_s +@@ -615,6 +646,15 @@ + */ + int t_handle_count; + ++ /* ++ * Protects the callback list ++ */ ++ spinlock_t t_jcb_lock; ++ /* ++ * List of registered callback functions for this transaction. ++ * Called when the transaction is committed. [t_jcb_lock] ++ */ ++ struct list_head t_jcb; + }; + + struct transaction_run_stats_s { +@@ -1018,6 +1058,9 @@ + extern int jbd2_journal_flush (journal_t *); + extern void jbd2_journal_lock_updates (journal_t *); + extern void jbd2_journal_unlock_updates (journal_t *); ++extern void jbd2_journal_callback_set(handle_t *handle, ++ void (*fn)(struct journal_callback *,int), ++ struct journal_callback *jcb); + + extern journal_t * jbd2_journal_init_dev(struct block_device *bdev, + struct block_device *fs_dev, +Index: linux-2.6.18-128.1.6/fs/jbd2/checkpoint.c +=================================================================== +--- linux-2.6.18-128.1.6.orig/fs/jbd2/checkpoint.c 2009-04-15 08:35:28.000000000 +0530 ++++ linux-2.6.18-128.1.6/fs/jbd2/checkpoint.c 2009-05-28 15:10:18.000000000 +0530 +@@ -695,6 +695,7 @@ + J_ASSERT(transaction->t_checkpoint_list == NULL); + J_ASSERT(transaction->t_checkpoint_io_list == NULL); + J_ASSERT(transaction->t_updates == 0); ++ J_ASSERT(list_empty(&transaction->t_jcb)); + J_ASSERT(journal->j_committing_transaction != transaction); + J_ASSERT(journal->j_running_transaction != transaction); + +Index: linux-2.6.18-128.1.6/fs/jbd2/commit.c +=================================================================== +--- linux-2.6.18-128.1.6.orig/fs/jbd2/commit.c 2009-04-15 08:35:28.000000000 +0530 ++++ linux-2.6.18-128.1.6/fs/jbd2/commit.c 2009-05-28 15:12:45.000000000 +0530 +@@ -898,6 +898,30 @@ + transaction can be removed from any checkpoint list it was on + before. */ + ++ /* ++ * Call any callbacks that had been registered for handles in this ++ * transaction. It is up to the callback to free any allocated ++ * memory. ++ * ++ * The spinlocking (t_jcb_lock) here is surely unnecessary... ++ */ ++ spin_lock(&commit_transaction->t_jcb_lock); ++ 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); ++ spin_unlock(&commit_transaction->t_jcb_lock); ++ jcb->jcb_func(jcb, error); ++ spin_lock(&commit_transaction->t_jcb_lock); ++ } ++ } ++ spin_unlock(&commit_transaction->t_jcb_lock); ++ + jbd_debug(3, "JBD: commit phase 7\n"); + + J_ASSERT(commit_transaction->t_sync_datalist == NULL); +Index: linux-2.6.18-128.1.6/fs/jbd2/journal.c +=================================================================== +--- linux-2.6.18-128.1.6.orig/fs/jbd2/journal.c 2009-04-15 08:35:28.000000000 +0530 ++++ linux-2.6.18-128.1.6/fs/jbd2/journal.c 2009-05-28 17:13:35.000000000 +0530 +@@ -80,6 +80,9 @@ + EXPORT_SYMBOL(jbd2_journal_invalidatepage); + EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers); + EXPORT_SYMBOL(jbd2_journal_force_commit); ++EXPORT_SYMBOL(jbd2_journal_callback_set); ++EXPORT_SYMBOL(jbd2_journal_bmap); ++EXPORT_SYMBOL(jbd2_log_start_commit); + + static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *); + static void __journal_abort_soft (journal_t *journal, int errno); +Index: linux-2.6.18-128.1.6/fs/jbd2/transaction.c +=================================================================== +--- linux-2.6.18-128.1.6.orig/fs/jbd2/transaction.c 2009-04-15 08:35:28.000000000 +0530 ++++ linux-2.6.18-128.1.6/fs/jbd2/transaction.c 2009-05-28 15:11:28.000000000 +0530 +@@ -51,6 +51,9 @@ + transaction->t_tid = journal->j_transaction_sequence++; + transaction->t_expires = jiffies + journal->j_commit_interval; + spin_lock_init(&transaction->t_handle_lock); ++ INIT_LIST_HEAD(&transaction->t_jcb); ++ spin_lock_init(&transaction->t_jcb_lock); ++ + + /* Set up the commit timer for the new transaction. */ + journal->j_commit_timer.expires = round_jiffies(transaction->t_expires); +@@ -251,6 +254,7 @@ + memset(handle, 0, sizeof(*handle)); + handle->h_buffer_credits = nblocks; + handle->h_ref = 1; ++ INIT_LIST_HEAD(&handle->h_jcb); + + lockdep_init_map(&handle->h_lockdep_map, "jbd2_handle", + &jbd2_handle_key, 0); +@@ -1349,6 +1353,36 @@ + } + + /** ++ * void jbd2_journal_callback_set() - Register a callback function for this handle. ++ * @handle: handle to attach the callback to. ++ * @func: function to callback. ++ * @jcb: structure with additional information required by func() , and ++ * some space for jbd2 internal information. ++ * ++ * The function will be ++ * called when the transaction that this handle is part of has been ++ * 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 ++ * allocated struct must start with a struct journal_callback at offset 0, ++ * and has the caller-specific data afterwards. ++ */ ++void jbd2_journal_callback_set(handle_t *handle, ++ void (*func)(struct journal_callback *jcb, int error), ++ struct journal_callback *jcb) ++{ ++ spin_lock(&handle->h_transaction->t_jcb_lock); ++ list_add_tail(&jcb->jcb_list, &handle->h_jcb); ++ spin_unlock(&handle->h_transaction->t_jcb_lock); ++ jcb->jcb_func = func; ++} ++ ++/** + * int jbd2_journal_stop() - complete a transaction + * @handle: tranaction to complete. + * +@@ -1422,6 +1456,11 @@ + wake_up(&journal->j_wait_transaction_locked); + } + ++ /* Move callbacks from the handle to the transaction. */ ++ spin_lock(&transaction->t_jcb_lock); ++ list_splice(&handle->h_jcb, &transaction->t_jcb); ++ spin_unlock(&transaction->t_jcb_lock); ++ + /* + * If the handle is marked SYNC, we need to set another commit + * going! We also want to force a commit if the current diff --git a/lustre/kernel_patches/series/2.6-rhel5.series b/lustre/kernel_patches/series/2.6-rhel5.series index 55f740a..2b00594 100644 --- a/lustre/kernel_patches/series/2.6-rhel5.series +++ b/lustre/kernel_patches/series/2.6-rhel5.series @@ -23,3 +23,4 @@ md-mmp-unplug-dev.patch prune-icache-use-trylock-rhel5.patch jbd-slab-race-2.6-rhel5.patch mpt-fusion-max-sge.patch +jbd2-jcberr-2.6-rhel5.patch