add patch fix-duplicate-label-for-phase-2-commit
[ext4-patch-queue.git] / transaction-reservation-support
blob37c4867e7b641ac8041a41647483729de01f92d6
1 jbd2: transaction reservation support
3 From: Jan Kara <jack@suse.cz>
5 In some cases we cannot start a transaction because of locking
6 constraints and passing started transaction into those places is not
7 handy either because we could block transaction commit for too long.
8 Transaction reservation is designed to solve these issues.  It
9 reserves a handle with given number of credits in the journal and the
10 handle can be later attached to the running transaction without
11 blocking on commit or checkpointing.  Reserved handles do not block
12 transaction commit in any way, they only reduce maximum size of the
13 running transaction (because we have to always be prepared to
14 accomodate request for attaching reserved handle).
16 Signed-off-by: Jan Kara <jack@suse.cz>
17 Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
18 ---
19  fs/ext4/ext4_jbd2.c   |   2 +-
20  fs/jbd2/commit.c      |   6 ++
21  fs/jbd2/journal.c     |   2 +
22  fs/jbd2/transaction.c | 328 +++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
23  include/linux/jbd2.h  |  28 ++++++-
24  5 files changed, 273 insertions(+), 93 deletions(-)
26 diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c
27 index 451eb40..bd25e78 100644
28 --- a/fs/ext4/ext4_jbd2.c
29 +++ b/fs/ext4/ext4_jbd2.c
30 @@ -62,7 +62,7 @@ handle_t *__ext4_journal_start_sb(struct super_block *sb, unsigned int line,
31                 ext4_abort(sb, "Detected aborted journal");
32                 return ERR_PTR(-EROFS);
33         }
34 -       return jbd2__journal_start(journal, nblocks, GFP_NOFS, type, line);
35 +       return jbd2__journal_start(journal, nblocks, 0, GFP_NOFS, type, line);
36  }
38  int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle)
39 diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c
40 index d73a0d8..cfbce48 100644
41 --- a/fs/jbd2/commit.c
42 +++ b/fs/jbd2/commit.c
43 @@ -523,6 +523,12 @@ void jbd2_journal_commit_transaction(journal_t *journal)
44          */
45         jbd2_journal_switch_revoke_table(journal);
47 +       /*
48 +        * Reserved credits cannot be claimed anymore, free them
49 +        */
50 +       atomic_sub(atomic_read(&journal->j_reserved_credits),
51 +                  &commit_transaction->t_outstanding_credits);
53         trace_jbd2_commit_flushing(journal, commit_transaction);
54         stats.run.rs_flushing = jiffies;
55         stats.run.rs_locked = jbd2_time_diff(stats.run.rs_locked,
56 diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
57 index f43f97b..70990d6 100644
58 --- a/fs/jbd2/journal.c
59 +++ b/fs/jbd2/journal.c
60 @@ -1030,6 +1030,7 @@ static journal_t * journal_init_common (void)
61         init_waitqueue_head(&journal->j_wait_done_commit);
62         init_waitqueue_head(&journal->j_wait_commit);
63         init_waitqueue_head(&journal->j_wait_updates);
64 +       init_waitqueue_head(&journal->j_wait_reserved);
65         mutex_init(&journal->j_barrier);
66         mutex_init(&journal->j_checkpoint_mutex);
67         spin_lock_init(&journal->j_revoke_lock);
68 @@ -1039,6 +1040,7 @@ static journal_t * journal_init_common (void)
69         journal->j_commit_interval = (HZ * JBD2_DEFAULT_MAX_COMMIT_AGE);
70         journal->j_min_batch_time = 0;
71         journal->j_max_batch_time = 15000; /* 15ms */
72 +       atomic_set(&journal->j_reserved_credits, 0);
74         /* The journal is marked for error until we succeed with recovery! */
75         journal->j_flags = JBD2_ABORT;
76 diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
77 index f14288b..f33342a 100644
78 --- a/fs/jbd2/transaction.c
79 +++ b/fs/jbd2/transaction.c
80 @@ -89,7 +89,8 @@ jbd2_get_transaction(journal_t *journal, transaction_t *transaction)
81         transaction->t_expires = jiffies + journal->j_commit_interval;
82         spin_lock_init(&transaction->t_handle_lock);
83         atomic_set(&transaction->t_updates, 0);
84 -       atomic_set(&transaction->t_outstanding_credits, 0);
85 +       atomic_set(&transaction->t_outstanding_credits,
86 +                  atomic_read(&journal->j_reserved_credits));
87         atomic_set(&transaction->t_handle_count, 0);
88         INIT_LIST_HEAD(&transaction->t_inode_list);
89         INIT_LIST_HEAD(&transaction->t_private_list);
90 @@ -141,6 +142,112 @@ static inline void update_t_max_wait(transaction_t *transaction,
91  }
93  /*
94 + * Wait until running transaction passes T_LOCKED state. Also starts the commit
95 + * if needed. The function expects running transaction to exist and releases
96 + * j_state_lock.
97 + */
98 +static void wait_transaction_locked(journal_t *journal)
99 +       __releases(journal->j_state_lock)
101 +       DEFINE_WAIT(wait);
102 +       int need_to_start;
103 +       tid_t tid = journal->j_running_transaction->t_tid;
105 +       prepare_to_wait(&journal->j_wait_transaction_locked, &wait,
106 +                       TASK_UNINTERRUPTIBLE);
107 +       need_to_start = !tid_geq(journal->j_commit_request, tid);
108 +       read_unlock(&journal->j_state_lock);
109 +       if (need_to_start)
110 +               jbd2_log_start_commit(journal, tid);
111 +       schedule();
112 +       finish_wait(&journal->j_wait_transaction_locked, &wait);
115 +static void sub_reserved_credits(journal_t *journal, int blocks)
117 +       atomic_sub(blocks, &journal->j_reserved_credits);
118 +       wake_up(&journal->j_wait_reserved);
122 + * Wait until we can add credits for handle to the running transaction.  Called
123 + * with j_state_lock held for reading. Returns 0 if handle joined the running
124 + * transaction. Returns 1 if we had to wait, j_state_lock is dropped, and
125 + * caller must retry.
126 + */
127 +static int add_transaction_credits(journal_t *journal, int blocks,
128 +                                  int rsv_blocks)
130 +       transaction_t *t = journal->j_running_transaction;
131 +       int needed;
132 +       int total = blocks + rsv_blocks;
134 +       /*
135 +        * If the current transaction is locked down for commit, wait
136 +        * for the lock to be released.
137 +        */
138 +       if (t->t_state == T_LOCKED) {
139 +               wait_transaction_locked(journal);
140 +               return 1;
141 +       }
143 +       /*
144 +        * If there is not enough space left in the log to write all
145 +        * potential buffers requested by this operation, we need to
146 +        * stall pending a log checkpoint to free some more log space.
147 +        */
148 +       needed = atomic_add_return(total, &t->t_outstanding_credits);
149 +       if (needed > journal->j_max_transaction_buffers) {
150 +               /*
151 +                * If the current transaction is already too large,
152 +                * then start to commit it: we can then go back and
153 +                * attach this handle to a new transaction.
154 +                */
155 +               atomic_sub(total, &t->t_outstanding_credits);
156 +               wait_transaction_locked(journal);
157 +               return 1;
158 +       }
160 +       /*
161 +        * The commit code assumes that it can get enough log space
162 +        * without forcing a checkpoint.  This is *critical* for
163 +        * correctness: a checkpoint of a buffer which is also
164 +        * associated with a committing transaction creates a deadlock,
165 +        * so commit simply cannot force through checkpoints.
166 +        *
167 +        * We must therefore ensure the necessary space in the journal
168 +        * *before* starting to dirty potentially checkpointed buffers
169 +        * in the new transaction.
170 +        */
171 +       if (jbd2_log_space_left(journal) < jbd2_space_needed(journal)) {
172 +               atomic_sub(total, &t->t_outstanding_credits);
173 +               read_unlock(&journal->j_state_lock);
174 +               write_lock(&journal->j_state_lock);
175 +               if (jbd2_log_space_left(journal) < jbd2_space_needed(journal))
176 +                       __jbd2_log_wait_for_space(journal);
177 +               write_unlock(&journal->j_state_lock);
178 +               return 1;
179 +       }
181 +       /* No reservation? We are done... */
182 +       if (!rsv_blocks)
183 +               return 0;
185 +       needed = atomic_add_return(rsv_blocks, &journal->j_reserved_credits);
186 +       /* We allow at most half of a transaction to be reserved */
187 +       if (needed > journal->j_max_transaction_buffers / 2) {
188 +               sub_reserved_credits(journal, rsv_blocks);
189 +               atomic_sub(total, &t->t_outstanding_credits);
190 +               read_unlock(&journal->j_state_lock);
191 +               wait_event(journal->j_wait_reserved,
192 +                        atomic_read(&journal->j_reserved_credits) + rsv_blocks
193 +                        <= journal->j_max_transaction_buffers / 2);
194 +               return 1;
195 +       }
196 +       return 0;
200   * start_this_handle: Given a handle, deal with any locking or stalling
201   * needed to make sure that there is enough journal space for the handle
202   * to begin.  Attach the handle to a transaction and set up the
203 @@ -151,18 +258,24 @@ static int start_this_handle(journal_t *journal, handle_t *handle,
204                              gfp_t gfp_mask)
206         transaction_t   *transaction, *new_transaction = NULL;
207 -       tid_t           tid;
208 -       int             needed, need_to_start;
209 -       int             nblocks = handle->h_buffer_credits;
210 +       int             blocks = handle->h_buffer_credits;
211 +       int             rsv_blocks = 0;
212         unsigned long ts = jiffies;
214 -       if (nblocks > journal->j_max_transaction_buffers) {
215 +       /*
216 +        * 1/2 of transaction can be reserved so we can practically handle
217 +        * only 1/2 of maximum transaction size per operation
218 +        */
219 +       if (WARN_ON(blocks > journal->j_max_transaction_buffers / 2)) {
220                 printk(KERN_ERR "JBD2: %s wants too many credits (%d > %d)\n",
221 -                      current->comm, nblocks,
222 -                      journal->j_max_transaction_buffers);
223 +                      current->comm, blocks,
224 +                      journal->j_max_transaction_buffers / 2);
225                 return -ENOSPC;
226         }
228 +       if (handle->h_rsv_handle)
229 +               rsv_blocks = handle->h_rsv_handle->h_buffer_credits;
231  alloc_transaction:
232         if (!journal->j_running_transaction) {
233                 new_transaction = kmem_cache_zalloc(transaction_cache,
234 @@ -199,8 +312,12 @@ repeat:
235                 return -EROFS;
236         }
238 -       /* Wait on the journal's transaction barrier if necessary */
239 -       if (journal->j_barrier_count) {
240 +       /*
241 +        * Wait on the journal's transaction barrier if necessary. Specifically
242 +        * we allow reserved handles to proceed because otherwise commit could
243 +        * deadlock on page writeback not being able to complete.
244 +        */
245 +       if (!handle->h_reserved && journal->j_barrier_count) {
246                 read_unlock(&journal->j_state_lock);
247                 wait_event(journal->j_wait_transaction_locked,
248                                 journal->j_barrier_count == 0);
249 @@ -213,7 +330,7 @@ repeat:
250                         goto alloc_transaction;
251                 write_lock(&journal->j_state_lock);
252                 if (!journal->j_running_transaction &&
253 -                   !journal->j_barrier_count) {
254 +                   (handle->h_reserved || !journal->j_barrier_count)) {
255                         jbd2_get_transaction(journal, new_transaction);
256                         new_transaction = NULL;
257                 }
258 @@ -223,75 +340,18 @@ repeat:
260         transaction = journal->j_running_transaction;
262 -       /*
263 -        * If the current transaction is locked down for commit, wait for the
264 -        * lock to be released.
265 -        */
266 -       if (transaction->t_state == T_LOCKED) {
267 -               DEFINE_WAIT(wait);
269 -               prepare_to_wait(&journal->j_wait_transaction_locked,
270 -                                       &wait, TASK_UNINTERRUPTIBLE);
271 -               read_unlock(&journal->j_state_lock);
272 -               schedule();
273 -               finish_wait(&journal->j_wait_transaction_locked, &wait);
274 -               goto repeat;
275 -       }
277 -       /*
278 -        * If there is not enough space left in the log to write all potential
279 -        * buffers requested by this operation, we need to stall pending a log
280 -        * checkpoint to free some more log space.
281 -        */
282 -       needed = atomic_add_return(nblocks,
283 -                                  &transaction->t_outstanding_credits);
285 -       if (needed > journal->j_max_transaction_buffers) {
286 +       if (!handle->h_reserved) {
287 +               /* We may have dropped j_state_lock - restart in that case */
288 +               if (add_transaction_credits(journal, blocks, rsv_blocks))
289 +                       goto repeat;
290 +       } else {
291                 /*
292 -                * If the current transaction is already too large, then start
293 -                * to commit it: we can then go back and attach this handle to
294 -                * a new transaction.
295 +                * We have handle reserved so we are allowed to join T_LOCKED
296 +                * transaction and we don't have to check for transaction size
297 +                * and journal space.
298                  */
299 -               DEFINE_WAIT(wait);
301 -               jbd_debug(2, "Handle %p starting new commit...\n", handle);
302 -               atomic_sub(nblocks, &transaction->t_outstanding_credits);
303 -               prepare_to_wait(&journal->j_wait_transaction_locked, &wait,
304 -                               TASK_UNINTERRUPTIBLE);
305 -               tid = transaction->t_tid;
306 -               need_to_start = !tid_geq(journal->j_commit_request, tid);
307 -               read_unlock(&journal->j_state_lock);
308 -               if (need_to_start)
309 -                       jbd2_log_start_commit(journal, tid);
310 -               schedule();
311 -               finish_wait(&journal->j_wait_transaction_locked, &wait);
312 -               goto repeat;
313 -       }
315 -       /*
316 -        * The commit code assumes that it can get enough log space
317 -        * without forcing a checkpoint.  This is *critical* for
318 -        * correctness: a checkpoint of a buffer which is also
319 -        * associated with a committing transaction creates a deadlock,
320 -        * so commit simply cannot force through checkpoints.
321 -        *
322 -        * We must therefore ensure the necessary space in the journal
323 -        * *before* starting to dirty potentially checkpointed buffers
324 -        * in the new transaction.
325 -        *
326 -        * The worst part is, any transaction currently committing can
327 -        * reduce the free space arbitrarily.  Be careful to account for
328 -        * those buffers when checkpointing.
329 -        */
330 -       if (jbd2_log_space_left(journal) < jbd2_space_needed(journal)) {
331 -               jbd_debug(2, "Handle %p waiting for checkpoint...\n", handle);
332 -               atomic_sub(nblocks, &transaction->t_outstanding_credits);
333 -               read_unlock(&journal->j_state_lock);
334 -               write_lock(&journal->j_state_lock);
335 -               if (jbd2_log_space_left(journal) < jbd2_space_needed(journal))
336 -                       __jbd2_log_wait_for_space(journal);
337 -               write_unlock(&journal->j_state_lock);
338 -               goto repeat;
339 +               sub_reserved_credits(journal, blocks);
340 +               handle->h_reserved = 0;
341         }
343         /* OK, account for the buffers that this operation expects to
344 @@ -299,12 +359,12 @@ repeat:
345          */
346         update_t_max_wait(transaction, ts);
347         handle->h_transaction = transaction;
348 -       handle->h_requested_credits = nblocks;
349 +       handle->h_requested_credits = blocks;
350         handle->h_start_jiffies = jiffies;
351         atomic_inc(&transaction->t_updates);
352         atomic_inc(&transaction->t_handle_count);
353 -       jbd_debug(4, "Handle %p given %d credits (total %d, free %d)\n",
354 -                 handle, nblocks,
355 +       jbd_debug(4, "Handle %p given %d credits (total %d, free %lu)\n",
356 +                 handle, blocks,
357                   atomic_read(&transaction->t_outstanding_credits),
358                   jbd2_log_space_left(journal));
359         read_unlock(&journal->j_state_lock);
360 @@ -338,16 +398,21 @@ static handle_t *new_handle(int nblocks)
361   *
362   * We make sure that the transaction can guarantee at least nblocks of
363   * modified buffers in the log.  We block until the log can guarantee
364 - * that much space.
365 - *
366 - * This function is visible to journal users (like ext3fs), so is not
367 - * called with the journal already locked.
368 + * that much space. Additionally, if rsv_blocks > 0, we also create another
369 + * handle with rsv_blocks reserved blocks in the journal. This handle is
370 + * is stored in h_rsv_handle. It is not attached to any particular transaction
371 + * and thus doesn't block transaction commit. If the caller uses this reserved
372 + * handle, it has to set h_rsv_handle to NULL as otherwise jbd2_journal_stop()
373 + * on the parent handle will dispose the reserved one. Reserved handle has to
374 + * be converted to a normal handle using jbd2_journal_start_reserved() before
375 + * it can be used.
376   *
377   * Return a pointer to a newly allocated handle, or an ERR_PTR() value
378   * on failure.
379   */
380 -handle_t *jbd2__journal_start(journal_t *journal, int nblocks, gfp_t gfp_mask,
381 -                             unsigned int type, unsigned int line_no)
382 +handle_t *jbd2__journal_start(journal_t *journal, int nblocks, int rsv_blocks,
383 +                             gfp_t gfp_mask, unsigned int type,
384 +                             unsigned int line_no)
386         handle_t *handle = journal_current_handle();
387         int err;
388 @@ -364,11 +429,25 @@ handle_t *jbd2__journal_start(journal_t *journal, int nblocks, gfp_t gfp_mask,
389         handle = new_handle(nblocks);
390         if (!handle)
391                 return ERR_PTR(-ENOMEM);
392 +       if (rsv_blocks) {
393 +               handle_t *rsv_handle;
395 +               rsv_handle = new_handle(rsv_blocks);
396 +               if (!rsv_handle) {
397 +                       jbd2_free_handle(handle);
398 +                       return ERR_PTR(-ENOMEM);
399 +               }
400 +               rsv_handle->h_reserved = 1;
401 +               rsv_handle->h_journal = journal;
402 +               handle->h_rsv_handle = rsv_handle;
403 +       }
405         current->journal_info = handle;
407         err = start_this_handle(journal, handle, gfp_mask);
408         if (err < 0) {
409 +               if (handle->h_rsv_handle)
410 +                       jbd2_free_handle(handle->h_rsv_handle);
411                 jbd2_free_handle(handle);
412                 current->journal_info = NULL;
413                 return ERR_PTR(err);
414 @@ -385,10 +464,68 @@ EXPORT_SYMBOL(jbd2__journal_start);
416  handle_t *jbd2_journal_start(journal_t *journal, int nblocks)
418 -       return jbd2__journal_start(journal, nblocks, GFP_NOFS, 0, 0);
419 +       return jbd2__journal_start(journal, nblocks, 0, GFP_NOFS, 0, 0);
421  EXPORT_SYMBOL(jbd2_journal_start);
423 +void jbd2_journal_free_reserved(handle_t *handle)
425 +       journal_t *journal = handle->h_journal;
427 +       WARN_ON(!handle->h_reserved);
428 +       sub_reserved_credits(journal, handle->h_buffer_credits);
429 +       jbd2_free_handle(handle);
431 +EXPORT_SYMBOL(jbd2_journal_free_reserved);
433 +/**
434 + * int jbd2_journal_start_reserved(handle_t *handle) - start reserved handle
435 + * @handle: handle to start
436 + *
437 + * Start handle that has been previously reserved with jbd2_journal_reserve().
438 + * This attaches @handle to the running transaction (or creates one if there's
439 + * not transaction running). Unlike jbd2_journal_start() this function cannot
440 + * block on journal commit, checkpointing, or similar stuff. It can block on
441 + * memory allocation or frozen journal though.
442 + *
443 + * Return 0 on success, non-zero on error - handle is freed in that case.
444 + */
445 +int jbd2_journal_start_reserved(handle_t *handle, unsigned int type,
446 +                               unsigned int line_no)
448 +       journal_t *journal = handle->h_journal;
449 +       int ret = -EIO;
451 +       if (WARN_ON(!handle->h_reserved)) {
452 +               /* Someone passed in normal handle? Just stop it. */
453 +               jbd2_journal_stop(handle);
454 +               return ret;
455 +       }
456 +       /*
457 +        * Usefulness of mixing of reserved and unreserved handles is
458 +        * questionable. So far nobody seems to need it so just error out.
459 +        */
460 +       if (WARN_ON(current->journal_info)) {
461 +               jbd2_journal_free_reserved(handle);
462 +               return ret;
463 +       }
465 +       handle->h_journal = NULL;
466 +       current->journal_info = handle;
467 +       /*
468 +        * GFP_NOFS is here because callers are likely from writeback or
469 +        * similarly constrained call sites
470 +        */
471 +       ret = start_this_handle(journal, handle, GFP_NOFS);
472 +       if (ret < 0) {
473 +               current->journal_info = NULL;
474 +               jbd2_journal_free_reserved(handle);
475 +       }
476 +       handle->h_type = type;
477 +       handle->h_line_no = line_no;
478 +       return ret;
480 +EXPORT_SYMBOL(jbd2_journal_start_reserved);
482  /**
483   * int jbd2_journal_extend() - extend buffer credits.
484 @@ -483,7 +620,8 @@ out:
485   * to a running handle, a call to jbd2_journal_restart will commit the
486   * handle's transaction so far and reattach the handle to a new
487   * transaction capabable of guaranteeing the requested number of
488 - * credits.
489 + * credits. We preserve reserved handle if there's any attached to the
490 + * passed in handle.
491   */
492  int jbd2__journal_restart(handle_t *handle, int nblocks, gfp_t gfp_mask)
494 @@ -508,6 +646,10 @@ int jbd2__journal_restart(handle_t *handle, int nblocks, gfp_t gfp_mask)
495         spin_lock(&transaction->t_handle_lock);
496         atomic_sub(handle->h_buffer_credits,
497                    &transaction->t_outstanding_credits);
498 +       if (handle->h_rsv_handle) {
499 +               sub_reserved_credits(journal,
500 +                                    handle->h_rsv_handle->h_buffer_credits);
501 +       }
502         if (atomic_dec_and_test(&transaction->t_updates))
503                 wake_up(&journal->j_wait_updates);
504         spin_unlock(&transaction->t_handle_lock);
505 @@ -550,6 +692,14 @@ void jbd2_journal_lock_updates(journal_t *journal)
506         write_lock(&journal->j_state_lock);
507         ++journal->j_barrier_count;
509 +       /* Wait until there are no reserved handles */
510 +       if (atomic_read(&journal->j_reserved_credits)) {
511 +               write_unlock(&journal->j_state_lock);
512 +               wait_event(journal->j_wait_reserved,
513 +                          atomic_read(&journal->j_reserved_credits) == 0);
514 +               write_lock(&journal->j_state_lock);
515 +       }
517         /* Wait until there are no running updates */
518         while (1) {
519                 transaction_t *transaction = journal->j_running_transaction;
520 @@ -1505,6 +1655,8 @@ int jbd2_journal_stop(handle_t *handle)
522         lock_map_release(&handle->h_lockdep_map);
524 +       if (handle->h_rsv_handle)
525 +               jbd2_journal_free_reserved(handle->h_rsv_handle);
526         jbd2_free_handle(handle);
527         return err;
529 diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
530 index 8028dd5..fb91c8d 100644
531 --- a/include/linux/jbd2.h
532 +++ b/include/linux/jbd2.h
533 @@ -410,8 +410,15 @@ struct jbd2_revoke_table_s;
535  struct jbd2_journal_handle
537 -       /* Which compound transaction is this update a part of? */
538 -       transaction_t           *h_transaction;
539 +       union {
540 +               /* Which compound transaction is this update a part of? */
541 +               transaction_t   *h_transaction;
542 +               /* Which journal handle belongs to - used iff h_reserved set */
543 +               journal_t       *h_journal;
544 +       };
546 +       /* Handle reserved for finishing the logical operation */
547 +       handle_t                *h_rsv_handle;
549         /* Number of remaining buffers we are allowed to dirty: */
550         int                     h_buffer_credits;
551 @@ -426,6 +433,7 @@ struct jbd2_journal_handle
552         /* Flags [no locking] */
553         unsigned int    h_sync:         1;      /* sync-on-close */
554         unsigned int    h_jdata:        1;      /* force data journaling */
555 +       unsigned int    h_reserved:     1;      /* handle with reserved credits */
556         unsigned int    h_aborted:      1;      /* fatal error on handle */
557         unsigned int    h_type:         8;      /* for handle statistics */
558         unsigned int    h_line_no:      16;     /* for handle statistics */
559 @@ -690,6 +698,7 @@ jbd2_time_diff(unsigned long start, unsigned long end)
560   * @j_wait_done_commit: Wait queue for waiting for commit to complete
561   * @j_wait_commit: Wait queue to trigger commit
562   * @j_wait_updates: Wait queue to wait for updates to complete
563 + * @j_wait_reserved: Wait queue to wait for reserved buffer credits to drop
564   * @j_checkpoint_mutex: Mutex for locking against concurrent checkpoints
565   * @j_head: Journal head - identifies the first unused block in the journal
566   * @j_tail: Journal tail - identifies the oldest still-used block in the
567 @@ -703,6 +712,7 @@ jbd2_time_diff(unsigned long start, unsigned long end)
568   *     journal
569   * @j_fs_dev: Device which holds the client fs.  For internal journal this will
570   *     be equal to j_dev
571 + * @j_reserved_credits: Number of buffers reserved from the running transaction
572   * @j_maxlen: Total maximum capacity of the journal region on disk.
573   * @j_list_lock: Protects the buffer lists and internal buffer state.
574   * @j_inode: Optional inode where we store the journal.  If present, all journal
575 @@ -801,6 +811,9 @@ struct journal_s
576         /* Wait queue to wait for updates to complete */
577         wait_queue_head_t       j_wait_updates;
579 +       /* Wait queue to wait for reserved buffer credits to drop */
580 +       wait_queue_head_t       j_wait_reserved;
582         /* Semaphore for locking against concurrent checkpoints */
583         struct mutex            j_checkpoint_mutex;
585 @@ -855,6 +868,9 @@ struct journal_s
586         /* Total maximum capacity of the journal region on disk. */
587         unsigned int            j_maxlen;
589 +       /* Number of buffers reserved from the running transaction */
590 +       atomic_t                j_reserved_credits;
592         /*
593          * Protects the buffer lists and internal buffer state.
594          */
595 @@ -1091,10 +1107,14 @@ static inline handle_t *journal_current_handle(void)
596   */
598  extern handle_t *jbd2_journal_start(journal_t *, int nblocks);
599 -extern handle_t *jbd2__journal_start(journal_t *, int nblocks, gfp_t gfp_mask,
600 -                                    unsigned int type, unsigned int line_no);
601 +extern handle_t *jbd2__journal_start(journal_t *, int blocks, int rsv_blocks,
602 +                                    gfp_t gfp_mask, unsigned int type,
603 +                                    unsigned int line_no);
604  extern int      jbd2_journal_restart(handle_t *, int nblocks);
605  extern int      jbd2__journal_restart(handle_t *, int nblocks, gfp_t gfp_mask);
606 +extern int      jbd2_journal_start_reserved(handle_t *handle,
607 +                               unsigned int type, unsigned int line_no);
608 +extern void     jbd2_journal_free_reserved(handle_t *handle);
609  extern int      jbd2_journal_extend (handle_t *, int nblocks);
610  extern int      jbd2_journal_get_write_access(handle_t *, struct buffer_head *);
611  extern int      jbd2_journal_get_create_access (handle_t *, struct buffer_head *);