Whamcloud - gitweb
b=19625
authorgirish <girish>
Fri, 22 May 2009 16:46:24 +0000 (16:46 +0000)
committergirish <girish>
Fri, 22 May 2009 16:46:24 +0000 (16:46 +0000)
i=johann
i=adilger

JBD2 kernel patch needed for ext4 support for SLES11

lustre/kernel_patches/patches/jbd2-jcberr-2.6-sles11.patch [new file with mode: 0644]
lustre/kernel_patches/series/2.6-sles11.series

diff --git a/lustre/kernel_patches/patches/jbd2-jcberr-2.6-sles11.patch b/lustre/kernel_patches/patches/jbd2-jcberr-2.6-sles11.patch
new file mode 100644 (file)
index 0000000..38555bb
--- /dev/null
@@ -0,0 +1,220 @@
+Index: linux-2.6.27.21-0.1/include/linux/jbd2.h
+===================================================================
+--- linux-2.6.27.21-0.1.orig/include/linux/jbd2.h
++++ linux-2.6.27.21-0.1/include/linux/jbd2.h
+@@ -413,6 +413,27 @@ struct jbd2_inode {
+       unsigned int i_flags;
+ };
++#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;
+ /**
+@@ -421,6 +442,7 @@ struct jbd2_revoke_table_s;
+  * @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
+@@ -446,6 +468,13 @@ struct handle_s
+       /* 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 */
+@@ -501,6 +530,8 @@ struct transaction_chp_stats_s {
+  *    j_state_lock
+  *    ->j_list_lock                   (journal_unmap_buffer)
+  *
++ *    t_handle_lock
++ *    ->t_jcb_lock
+  */
+ struct transaction_s
+@@ -641,6 +672,15 @@ struct transaction_s
+        */
+       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 {
+@@ -1044,6 +1084,9 @@ extern int        jbd2_journal_stop(handle_t *
+ 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.27.21-0.1/fs/jbd2/checkpoint.c
+===================================================================
+--- linux-2.6.27.21-0.1.orig/fs/jbd2/checkpoint.c
++++ linux-2.6.27.21-0.1/fs/jbd2/checkpoint.c
+@@ -728,6 +728,7 @@ void __jbd2_journal_drop_transaction(jou
+       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.27.21-0.1/fs/jbd2/commit.c
+===================================================================
+--- linux-2.6.27.21-0.1.orig/fs/jbd2/commit.c
++++ linux-2.6.27.21-0.1/fs/jbd2/commit.c
+@@ -928,6 +928,30 @@ restart_loop:
+       /* Done with this transaction! */
++      /*
++       * 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_state == T_COMMIT);
+Index: linux-2.6.27.21-0.1/fs/jbd2/journal.c
+===================================================================
+--- linux-2.6.27.21-0.1.orig/fs/jbd2/journal.c
++++ linux-2.6.27.21-0.1/fs/jbd2/journal.c
+@@ -84,6 +84,8 @@ EXPORT_SYMBOL(jbd2_journal_file_inode);
+ EXPORT_SYMBOL(jbd2_journal_init_jbd_inode);
+ EXPORT_SYMBOL(jbd2_journal_release_jbd_inode);
+ EXPORT_SYMBOL(jbd2_journal_begin_ordered_truncate);
++EXPORT_SYMBOL(jbd2_journal_callback_set);
++EXPORT_SYMBOL(jbd2_journal_bmap);
+ 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.27.21-0.1/fs/jbd2/transaction.c
+===================================================================
+--- linux-2.6.27.21-0.1.orig/fs/jbd2/transaction.c
++++ linux-2.6.27.21-0.1/fs/jbd2/transaction.c
+@@ -50,7 +50,9 @@ jbd2_get_transaction(journal_t *journal,
+       transaction->t_state = T_RUNNING;
+       transaction->t_tid = journal->j_transaction_sequence++;
+       transaction->t_expires = jiffies + journal->j_commit_interval;
++      INIT_LIST_HEAD(&transaction->t_jcb);
+       spin_lock_init(&transaction->t_handle_lock);
++      spin_lock_init(&transaction->t_jcb_lock);
+       INIT_LIST_HEAD(&transaction->t_inode_list);
+       /* Set up the commit timer for the new transaction. */
+@@ -252,6 +254,7 @@ static handle_t *new_handle(int nblocks)
+       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);
+@@ -1173,6 +1176,36 @@ drop:
+ }
+ /**
++ * 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.
+  *
+@@ -1246,6 +1279,11 @@ int jbd2_journal_stop(handle_t *handle)
+                       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
index 8d11a57..298cf0a 100644 (file)
@@ -9,3 +9,4 @@ export-show_task-2.6.27-vanilla.patch
 sd_iostats-2.6.27-vanilla.patch
 md-mmp-unplug-dev-sles11.patch
 quota-support-64-bit-quota-format.patch
+jbd2-jcberr-2.6-sles11.patch