checkpoint.c (214eb5a4d8a2032fb9f0711d1b202eb88ee02920) | checkpoint.c (4ba3fcdde7e36af93610ceb3cc38365b14539865) |
---|---|
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * linux/fs/jbd2/checkpoint.c 4 * 5 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999 6 * 7 * Copyright 1999 Red Hat Software --- All Rights Reserved 8 * --- 66 unchanged lines hidden (view full) --- 75 jh->b_cpprev = transaction->t_checkpoint_io_list->b_cpprev; 76 jh->b_cpprev->b_cpnext = jh; 77 jh->b_cpnext->b_cpprev = jh; 78 } 79 transaction->t_checkpoint_io_list = jh; 80} 81 82/* | 1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * linux/fs/jbd2/checkpoint.c 4 * 5 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999 6 * 7 * Copyright 1999 Red Hat Software --- All Rights Reserved 8 * --- 66 unchanged lines hidden (view full) --- 75 jh->b_cpprev = transaction->t_checkpoint_io_list->b_cpprev; 76 jh->b_cpprev->b_cpnext = jh; 77 jh->b_cpnext->b_cpprev = jh; 78 } 79 transaction->t_checkpoint_io_list = jh; 80} 81 82/* |
83 * Check a checkpoint buffer could be release or not. 84 * 85 * Requires j_list_lock 86 */ 87static inline bool __cp_buffer_busy(struct journal_head *jh) 88{ 89 struct buffer_head *bh = jh2bh(jh); 90 91 return (jh->b_transaction || buffer_locked(bh) || buffer_dirty(bh)); 92} 93 94/* |
|
83 * Try to release a checkpointed buffer from its transaction. 84 * Returns 1 if we released it and 2 if we also released the 85 * whole transaction. 86 * 87 * Requires j_list_lock 88 */ 89static int __try_to_free_cp_buf(struct journal_head *jh) 90{ --- 363 unchanged lines hidden (view full) --- 454 if (need_resched()) 455 return 0; 456 } while (jh != last_jh); 457 458 return 0; 459} 460 461/* | 95 * Try to release a checkpointed buffer from its transaction. 96 * Returns 1 if we released it and 2 if we also released the 97 * whole transaction. 98 * 99 * Requires j_list_lock 100 */ 101static int __try_to_free_cp_buf(struct journal_head *jh) 102{ --- 363 unchanged lines hidden (view full) --- 466 if (need_resched()) 467 return 0; 468 } while (jh != last_jh); 469 470 return 0; 471} 472 473/* |
474 * journal_shrink_one_cp_list 475 * 476 * Find 'nr_to_scan' written-back checkpoint buffers in the given list 477 * and try to release them. If the whole transaction is released, set 478 * the 'released' parameter. Return the number of released checkpointed 479 * buffers. 480 * 481 * Called with j_list_lock held. 482 */ 483static unsigned long journal_shrink_one_cp_list(struct journal_head *jh, 484 unsigned long *nr_to_scan, 485 bool *released) 486{ 487 struct journal_head *last_jh; 488 struct journal_head *next_jh = jh; 489 unsigned long nr_freed = 0; 490 int ret; 491 492 if (!jh || *nr_to_scan == 0) 493 return 0; 494 495 last_jh = jh->b_cpprev; 496 do { 497 jh = next_jh; 498 next_jh = jh->b_cpnext; 499 500 (*nr_to_scan)--; 501 if (__cp_buffer_busy(jh)) 502 continue; 503 504 nr_freed++; 505 ret = __jbd2_journal_remove_checkpoint(jh); 506 if (ret) { 507 *released = true; 508 break; 509 } 510 511 if (need_resched()) 512 break; 513 } while (jh != last_jh && *nr_to_scan); 514 515 return nr_freed; 516} 517 518/* 519 * jbd2_journal_shrink_checkpoint_list 520 * 521 * Find 'nr_to_scan' written-back checkpoint buffers in the journal 522 * and try to release them. Return the number of released checkpointed 523 * buffers. 524 * 525 * Called with j_list_lock held. 526 */ 527unsigned long jbd2_journal_shrink_checkpoint_list(journal_t *journal, 528 unsigned long *nr_to_scan) 529{ 530 transaction_t *transaction, *last_transaction, *next_transaction; 531 bool released; 532 tid_t first_tid = 0, last_tid = 0, next_tid = 0; 533 tid_t tid = 0; 534 unsigned long nr_freed = 0; 535 unsigned long nr_scanned = *nr_to_scan; 536 537again: 538 spin_lock(&journal->j_list_lock); 539 if (!journal->j_checkpoint_transactions) { 540 spin_unlock(&journal->j_list_lock); 541 goto out; 542 } 543 544 /* 545 * Get next shrink transaction, resume previous scan or start 546 * over again. If some others do checkpoint and drop transaction 547 * from the checkpoint list, we ignore saved j_shrink_transaction 548 * and start over unconditionally. 549 */ 550 if (journal->j_shrink_transaction) 551 transaction = journal->j_shrink_transaction; 552 else 553 transaction = journal->j_checkpoint_transactions; 554 555 if (!first_tid) 556 first_tid = transaction->t_tid; 557 last_transaction = journal->j_checkpoint_transactions->t_cpprev; 558 next_transaction = transaction; 559 last_tid = last_transaction->t_tid; 560 do { 561 transaction = next_transaction; 562 next_transaction = transaction->t_cpnext; 563 tid = transaction->t_tid; 564 released = false; 565 566 nr_freed += journal_shrink_one_cp_list(transaction->t_checkpoint_list, 567 nr_to_scan, &released); 568 if (*nr_to_scan == 0) 569 break; 570 if (need_resched() || spin_needbreak(&journal->j_list_lock)) 571 break; 572 if (released) 573 continue; 574 575 nr_freed += journal_shrink_one_cp_list(transaction->t_checkpoint_io_list, 576 nr_to_scan, &released); 577 if (*nr_to_scan == 0) 578 break; 579 if (need_resched() || spin_needbreak(&journal->j_list_lock)) 580 break; 581 } while (transaction != last_transaction); 582 583 if (transaction != last_transaction) { 584 journal->j_shrink_transaction = next_transaction; 585 next_tid = next_transaction->t_tid; 586 } else { 587 journal->j_shrink_transaction = NULL; 588 next_tid = 0; 589 } 590 591 spin_unlock(&journal->j_list_lock); 592 cond_resched(); 593 594 if (*nr_to_scan && next_tid) 595 goto again; 596out: 597 nr_scanned -= *nr_to_scan; 598 trace_jbd2_shrink_checkpoint_list(journal, first_tid, tid, last_tid, 599 nr_freed, nr_scanned, next_tid); 600 601 return nr_freed; 602} 603 604/* |
|
462 * journal_clean_checkpoint_list 463 * 464 * Find all the written-back checkpoint buffers in the journal and release them. 465 * If 'destroy' is set, release all buffers unconditionally. 466 * 467 * Called with j_list_lock held. 468 */ 469void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy) --- 105 unchanged lines hidden (view full) --- 575 * jbd2_journal_destroy(). So mark the writeback IO error in the 576 * journal here and we abort the journal later from a better context. 577 */ 578 if (buffer_write_io_error(bh)) 579 set_bit(JBD2_CHECKPOINT_IO_ERROR, &journal->j_atomic_flags); 580 581 __buffer_unlink(jh); 582 jh->b_cp_transaction = NULL; | 605 * journal_clean_checkpoint_list 606 * 607 * Find all the written-back checkpoint buffers in the journal and release them. 608 * If 'destroy' is set, release all buffers unconditionally. 609 * 610 * Called with j_list_lock held. 611 */ 612void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy) --- 105 unchanged lines hidden (view full) --- 718 * jbd2_journal_destroy(). So mark the writeback IO error in the 719 * journal here and we abort the journal later from a better context. 720 */ 721 if (buffer_write_io_error(bh)) 722 set_bit(JBD2_CHECKPOINT_IO_ERROR, &journal->j_atomic_flags); 723 724 __buffer_unlink(jh); 725 jh->b_cp_transaction = NULL; |
726 percpu_counter_dec(&journal->j_jh_shrink_count); |
|
583 jbd2_journal_put_journal_head(jh); 584 585 /* Is this transaction empty? */ 586 if (transaction->t_checkpoint_list || transaction->t_checkpoint_io_list) 587 return 0; 588 589 /* 590 * There is one special case to worry about: if we have just pulled the --- 46 unchanged lines hidden (view full) --- 637 jh->b_cpnext = jh->b_cpprev = jh; 638 } else { 639 jh->b_cpnext = transaction->t_checkpoint_list; 640 jh->b_cpprev = transaction->t_checkpoint_list->b_cpprev; 641 jh->b_cpprev->b_cpnext = jh; 642 jh->b_cpnext->b_cpprev = jh; 643 } 644 transaction->t_checkpoint_list = jh; | 727 jbd2_journal_put_journal_head(jh); 728 729 /* Is this transaction empty? */ 730 if (transaction->t_checkpoint_list || transaction->t_checkpoint_io_list) 731 return 0; 732 733 /* 734 * There is one special case to worry about: if we have just pulled the --- 46 unchanged lines hidden (view full) --- 781 jh->b_cpnext = jh->b_cpprev = jh; 782 } else { 783 jh->b_cpnext = transaction->t_checkpoint_list; 784 jh->b_cpprev = transaction->t_checkpoint_list->b_cpprev; 785 jh->b_cpprev->b_cpnext = jh; 786 jh->b_cpnext->b_cpprev = jh; 787 } 788 transaction->t_checkpoint_list = jh; |
789 percpu_counter_inc(&transaction->t_journal->j_jh_shrink_count); |
|
645} 646 647/* 648 * We've finished with this transaction structure: adios... 649 * 650 * The transaction must have no links except for the checkpoint by this 651 * point. 652 * 653 * Called with the journal locked. 654 * Called with j_list_lock held. 655 */ 656 657void __jbd2_journal_drop_transaction(journal_t *journal, transaction_t *transaction) 658{ 659 assert_spin_locked(&journal->j_list_lock); | 790} 791 792/* 793 * We've finished with this transaction structure: adios... 794 * 795 * The transaction must have no links except for the checkpoint by this 796 * point. 797 * 798 * Called with the journal locked. 799 * Called with j_list_lock held. 800 */ 801 802void __jbd2_journal_drop_transaction(journal_t *journal, transaction_t *transaction) 803{ 804 assert_spin_locked(&journal->j_list_lock); |
805 806 journal->j_shrink_transaction = NULL; |
|
660 if (transaction->t_cpnext) { 661 transaction->t_cpnext->t_cpprev = transaction->t_cpprev; 662 transaction->t_cpprev->t_cpnext = transaction->t_cpnext; 663 if (journal->j_checkpoint_transactions == transaction) 664 journal->j_checkpoint_transactions = 665 transaction->t_cpnext; 666 if (journal->j_checkpoint_transactions == transaction) 667 journal->j_checkpoint_transactions = NULL; --- 16 unchanged lines hidden --- | 807 if (transaction->t_cpnext) { 808 transaction->t_cpnext->t_cpprev = transaction->t_cpprev; 809 transaction->t_cpprev->t_cpnext = transaction->t_cpnext; 810 if (journal->j_checkpoint_transactions == transaction) 811 journal->j_checkpoint_transactions = 812 transaction->t_cpnext; 813 if (journal->j_checkpoint_transactions == transaction) 814 journal->j_checkpoint_transactions = NULL; --- 16 unchanged lines hidden --- |