return ret;
 }
 
-#define NR_BATCH       64
-
 static void
-__flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count)
+__flush_batch(journal_t *journal, int *batch_count)
 {
        int i;
 
-       ll_rw_block(SWRITE, *batch_count, bhs);
+       ll_rw_block(SWRITE, *batch_count, journal->j_chkpt_bhs);
        for (i = 0; i < *batch_count; i++) {
-               struct buffer_head *bh = bhs[i];
+               struct buffer_head *bh = journal->j_chkpt_bhs[i];
                clear_buffer_jwrite(bh);
                BUFFER_TRACE(bh, "brelse");
                __brelse(bh);
  * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
  */
 static int __process_buffer(journal_t *journal, struct journal_head *jh,
-                       struct buffer_head **bhs, int *batch_count,
-                       transaction_t *transaction)
+                           int *batch_count, transaction_t *transaction)
 {
        struct buffer_head *bh = jh2bh(jh);
        int ret = 0;
                get_bh(bh);
                J_ASSERT_BH(bh, !buffer_jwrite(bh));
                set_buffer_jwrite(bh);
-               bhs[*batch_count] = bh;
+               journal->j_chkpt_bhs[*batch_count] = bh;
                __buffer_relink_io(jh);
                jbd_unlock_bh_state(bh);
                transaction->t_chp_stats.cs_written++;
                (*batch_count)++;
-               if (*batch_count == NR_BATCH) {
+               if (*batch_count == JBD2_NR_BATCH) {
                        spin_unlock(&journal->j_list_lock);
-                       __flush_batch(journal, bhs, batch_count);
+                       __flush_batch(journal, batch_count);
                        ret = 1;
                }
        }
        if (journal->j_checkpoint_transactions == transaction &&
                        transaction->t_tid == this_tid) {
                int batch_count = 0;
-               struct buffer_head *bhs[NR_BATCH];
                struct journal_head *jh;
                int retry = 0, err;
 
                                retry = 1;
                                break;
                        }
-                       retry = __process_buffer(journal, jh, bhs, &batch_count,
+                       retry = __process_buffer(journal, jh, &batch_count,
                                                 transaction);
                        if (retry < 0 && !result)
                                result = retry;
                                spin_unlock(&journal->j_list_lock);
                                retry = 1;
                        }
-                       __flush_batch(journal, bhs, &batch_count);
+                       __flush_batch(journal, &batch_count);
                }
 
                if (retry) {
 
        return end + (MAX_JIFFY_OFFSET - start);
 }
 
+#define JBD2_NR_BATCH  64
+
 /**
  * struct journal_s - The journal_s type is the concrete type associated with
  *     journal_t.
        /* Semaphore for locking against concurrent checkpoints */
        struct mutex            j_checkpoint_mutex;
 
+       /*
+        * List of buffer heads used by the checkpoint routine.  This
+        * was moved from jbd2_log_do_checkpoint() to reduce stack
+        * usage.  Access to this array is controlled by the
+        * j_checkpoint_mutex.  [j_checkpoint_mutex]
+        */
+       struct buffer_head      *j_chkpt_bhs[JBD2_NR_BATCH];
+       
        /*
         * Journal head: identifies the first unused block in the journal.
         * [j_state_lock]