aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/jbd2/checkpoint.c56
-rw-r--r--include/linux/jbd2.h2
2 files changed, 25 insertions, 33 deletions
diff --git a/fs/jbd2/checkpoint.c b/fs/jbd2/checkpoint.c
index 3ab4c5ee12ce..988b32ed4c87 100644
--- a/fs/jbd2/checkpoint.c
+++ b/fs/jbd2/checkpoint.c
@@ -421,16 +421,15 @@ int jbd2_cleanup_journal_tail(journal_t *journal)
421 * release them. 421 * release them.
422 * 422 *
423 * Called with j_list_lock held. 423 * Called with j_list_lock held.
424 * Returns number of buffers reaped (for debug) 424 * Returns 1 if we freed the transaction, 0 otherwise.
425 */ 425 */
426 426static int journal_clean_one_cp_list(struct journal_head *jh)
427static int journal_clean_one_cp_list(struct journal_head *jh, int *released)
428{ 427{
429 struct journal_head *last_jh; 428 struct journal_head *last_jh;
430 struct journal_head *next_jh = jh; 429 struct journal_head *next_jh = jh;
431 int ret, freed = 0; 430 int ret;
431 int freed = 0;
432 432
433 *released = 0;
434 if (!jh) 433 if (!jh)
435 return 0; 434 return 0;
436 435
@@ -441,11 +440,9 @@ static int journal_clean_one_cp_list(struct journal_head *jh, int *released)
441 ret = __try_to_free_cp_buf(jh); 440 ret = __try_to_free_cp_buf(jh);
442 if (!ret) 441 if (!ret)
443 return freed; 442 return freed;
444 freed++; 443 if (ret == 2)
445 if (ret == 2) { 444 return 1;
446 *released = 1; 445 freed = 1;
447 return freed;
448 }
449 /* 446 /*
450 * This function only frees up some memory 447 * This function only frees up some memory
451 * if possible so we dont have an obligation 448 * if possible so we dont have an obligation
@@ -465,53 +462,48 @@ static int journal_clean_one_cp_list(struct journal_head *jh, int *released)
465 * Find all the written-back checkpoint buffers in the journal and release them. 462 * Find all the written-back checkpoint buffers in the journal and release them.
466 * 463 *
467 * Called with j_list_lock held. 464 * Called with j_list_lock held.
468 * Returns number of buffers reaped (for debug)
469 */ 465 */
470 466void __jbd2_journal_clean_checkpoint_list(journal_t *journal)
471int __jbd2_journal_clean_checkpoint_list(journal_t *journal)
472{ 467{
473 transaction_t *transaction, *last_transaction, *next_transaction; 468 transaction_t *transaction, *last_transaction, *next_transaction;
474 int ret; 469 int ret;
475 int freed = 0;
476 int released;
477 470
478 transaction = journal->j_checkpoint_transactions; 471 transaction = journal->j_checkpoint_transactions;
479 if (!transaction) 472 if (!transaction)
480 goto out; 473 return;
481 474
482 last_transaction = transaction->t_cpprev; 475 last_transaction = transaction->t_cpprev;
483 next_transaction = transaction; 476 next_transaction = transaction;
484 do { 477 do {
485 transaction = next_transaction; 478 transaction = next_transaction;
486 next_transaction = transaction->t_cpnext; 479 next_transaction = transaction->t_cpnext;
487 ret = journal_clean_one_cp_list(transaction-> 480 ret = journal_clean_one_cp_list(transaction->t_checkpoint_list);
488 t_checkpoint_list, &released);
489 /* 481 /*
490 * This function only frees up some memory if possible so we 482 * This function only frees up some memory if possible so we
491 * dont have an obligation to finish processing. Bail out if 483 * dont have an obligation to finish processing. Bail out if
492 * preemption requested: 484 * preemption requested:
493 */ 485 */
494 if (need_resched()) { 486 if (need_resched())
495 freed += ret; 487 return;
496 goto out; 488 if (ret)
497 }
498 if (released) {
499 freed += ret;
500 continue; 489 continue;
501 }
502 /* 490 /*
503 * It is essential that we are as careful as in the case of 491 * It is essential that we are as careful as in the case of
504 * t_checkpoint_list with removing the buffer from the list as 492 * t_checkpoint_list with removing the buffer from the list as
505 * we can possibly see not yet submitted buffers on io_list 493 * we can possibly see not yet submitted buffers on io_list
506 */ 494 */
507 ret += journal_clean_one_cp_list(transaction-> 495 ret = journal_clean_one_cp_list(transaction->
508 t_checkpoint_io_list, &released); 496 t_checkpoint_io_list);
509 freed += ret; 497 if (need_resched())
510 if (need_resched() || !ret) 498 return;
511 goto out; 499 /*
500 * Stop scanning if we couldn't free the transaction. This
501 * avoids pointless scanning of transactions which still
502 * weren't checkpointed.
503 */
504 if (!ret)
505 return;
512 } while (transaction != last_transaction); 506 } while (transaction != last_transaction);
513out:
514 return freed;
515} 507}
516 508
517/* 509/*
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
index 0dae71e9971c..704b9a599b26 100644
--- a/include/linux/jbd2.h
+++ b/include/linux/jbd2.h
@@ -1042,7 +1042,7 @@ void jbd2_update_log_tail(journal_t *journal, tid_t tid, unsigned long block);
1042extern void jbd2_journal_commit_transaction(journal_t *); 1042extern void jbd2_journal_commit_transaction(journal_t *);
1043 1043
1044/* Checkpoint list management */ 1044/* Checkpoint list management */
1045int __jbd2_journal_clean_checkpoint_list(journal_t *journal); 1045void __jbd2_journal_clean_checkpoint_list(journal_t *journal);
1046int __jbd2_journal_remove_checkpoint(struct journal_head *); 1046int __jbd2_journal_remove_checkpoint(struct journal_head *);
1047void __jbd2_journal_insert_checkpoint(struct journal_head *, transaction_t *); 1047void __jbd2_journal_insert_checkpoint(struct journal_head *, transaction_t *);
1048 1048