checkpoint.c (be22255360f80d3af789daad00025171a65424a5) checkpoint.c (b98dba273a0e47dbfade89c9af73c5b012a4eabb)
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 *

--- 334 unchanged lines hidden (view full) ---

343
344 return __jbd2_update_log_tail(journal, first_tid, blocknr);
345}
346
347
348/* Checkpoint list management */
349
350/*
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 *

--- 334 unchanged lines hidden (view full) ---

343
344 return __jbd2_update_log_tail(journal, first_tid, blocknr);
345}
346
347
348/* Checkpoint list management */
349
350/*
351 * journal_clean_one_cp_list
352 *
353 * Find all the written-back checkpoint buffers in the given list and
354 * release them. If 'destroy' is set, clean all buffers unconditionally.
355 *
356 * Called with j_list_lock held.
357 * Returns 1 if we freed the transaction, 0 otherwise.
358 */
359static int journal_clean_one_cp_list(struct journal_head *jh, bool destroy)
360{
361 struct journal_head *last_jh;
362 struct journal_head *next_jh = jh;
363
364 if (!jh)
365 return 0;
366
367 last_jh = jh->b_cpprev;
368 do {
369 jh = next_jh;
370 next_jh = jh->b_cpnext;
371
372 if (!destroy && __cp_buffer_busy(jh))
373 return 0;
374
375 if (__jbd2_journal_remove_checkpoint(jh))
376 return 1;
377 /*
378 * This function only frees up some memory
379 * if possible so we dont have an obligation
380 * to finish processing. Bail out if preemption
381 * requested:
382 */
383 if (need_resched())
384 return 0;
385 } while (jh != last_jh);
386
387 return 0;
388}
389
390/*
391 * journal_shrink_one_cp_list
392 *
351 * journal_shrink_one_cp_list
352 *
393 * Find 'nr_to_scan' written-back checkpoint buffers in the given list
353 * Find all the written-back checkpoint buffers in the given list
394 * and try to release them. If the whole transaction is released, set
395 * the 'released' parameter. Return the number of released checkpointed
396 * buffers.
397 *
398 * Called with j_list_lock held.
399 */
400static unsigned long journal_shrink_one_cp_list(struct journal_head *jh,
354 * and try to release them. If the whole transaction is released, set
355 * the 'released' parameter. Return the number of released checkpointed
356 * buffers.
357 *
358 * Called with j_list_lock held.
359 */
360static unsigned long journal_shrink_one_cp_list(struct journal_head *jh,
401 unsigned long *nr_to_scan,
402 bool *released)
361 bool destroy, bool *released)
403{
404 struct journal_head *last_jh;
405 struct journal_head *next_jh = jh;
406 unsigned long nr_freed = 0;
407 int ret;
408
362{
363 struct journal_head *last_jh;
364 struct journal_head *next_jh = jh;
365 unsigned long nr_freed = 0;
366 int ret;
367
409 if (!jh || *nr_to_scan == 0)
368 *released = false;
369 if (!jh)
410 return 0;
411
412 last_jh = jh->b_cpprev;
413 do {
414 jh = next_jh;
415 next_jh = jh->b_cpnext;
416
370 return 0;
371
372 last_jh = jh->b_cpprev;
373 do {
374 jh = next_jh;
375 next_jh = jh->b_cpnext;
376
417 (*nr_to_scan)--;
418 if (__cp_buffer_busy(jh))
377 if (!destroy && __cp_buffer_busy(jh))
419 continue;
420
421 nr_freed++;
422 ret = __jbd2_journal_remove_checkpoint(jh);
423 if (ret) {
424 *released = true;
425 break;
426 }
427
428 if (need_resched())
429 break;
378 continue;
379
380 nr_freed++;
381 ret = __jbd2_journal_remove_checkpoint(jh);
382 if (ret) {
383 *released = true;
384 break;
385 }
386
387 if (need_resched())
388 break;
430 } while (jh != last_jh && *nr_to_scan);
389 } while (jh != last_jh);
431
432 return nr_freed;
433}
434
435/*
436 * jbd2_journal_shrink_checkpoint_list
437 *
438 * Find 'nr_to_scan' written-back checkpoint buffers in the journal
439 * and try to release them. Return the number of released checkpointed
440 * buffers.
441 *
442 * Called with j_list_lock held.
443 */
444unsigned long jbd2_journal_shrink_checkpoint_list(journal_t *journal,
445 unsigned long *nr_to_scan)
446{
447 transaction_t *transaction, *last_transaction, *next_transaction;
390
391 return nr_freed;
392}
393
394/*
395 * jbd2_journal_shrink_checkpoint_list
396 *
397 * Find 'nr_to_scan' written-back checkpoint buffers in the journal
398 * and try to release them. Return the number of released checkpointed
399 * buffers.
400 *
401 * Called with j_list_lock held.
402 */
403unsigned long jbd2_journal_shrink_checkpoint_list(journal_t *journal,
404 unsigned long *nr_to_scan)
405{
406 transaction_t *transaction, *last_transaction, *next_transaction;
448 bool released;
407 bool __maybe_unused released;
449 tid_t first_tid = 0, last_tid = 0, next_tid = 0;
450 tid_t tid = 0;
451 unsigned long nr_freed = 0;
408 tid_t first_tid = 0, last_tid = 0, next_tid = 0;
409 tid_t tid = 0;
410 unsigned long nr_freed = 0;
452 unsigned long nr_scanned = *nr_to_scan;
411 unsigned long freed;
453
454again:
455 spin_lock(&journal->j_list_lock);
456 if (!journal->j_checkpoint_transactions) {
457 spin_unlock(&journal->j_list_lock);
458 goto out;
459 }
460

--- 12 unchanged lines hidden (view full) ---

473 first_tid = transaction->t_tid;
474 last_transaction = journal->j_checkpoint_transactions->t_cpprev;
475 next_transaction = transaction;
476 last_tid = last_transaction->t_tid;
477 do {
478 transaction = next_transaction;
479 next_transaction = transaction->t_cpnext;
480 tid = transaction->t_tid;
412
413again:
414 spin_lock(&journal->j_list_lock);
415 if (!journal->j_checkpoint_transactions) {
416 spin_unlock(&journal->j_list_lock);
417 goto out;
418 }
419

--- 12 unchanged lines hidden (view full) ---

432 first_tid = transaction->t_tid;
433 last_transaction = journal->j_checkpoint_transactions->t_cpprev;
434 next_transaction = transaction;
435 last_tid = last_transaction->t_tid;
436 do {
437 transaction = next_transaction;
438 next_transaction = transaction->t_cpnext;
439 tid = transaction->t_tid;
481 released = false;
482
440
483 nr_freed += journal_shrink_one_cp_list(transaction->t_checkpoint_list,
484 nr_to_scan, &released);
441 freed = journal_shrink_one_cp_list(transaction->t_checkpoint_list,
442 false, &released);
443 nr_freed += freed;
444 (*nr_to_scan) -= min(*nr_to_scan, freed);
485 if (*nr_to_scan == 0)
486 break;
487 if (need_resched() || spin_needbreak(&journal->j_list_lock))
488 break;
489 } while (transaction != last_transaction);
490
491 if (transaction != last_transaction) {
492 journal->j_shrink_transaction = next_transaction;

--- 4 unchanged lines hidden (view full) ---

497 }
498
499 spin_unlock(&journal->j_list_lock);
500 cond_resched();
501
502 if (*nr_to_scan && next_tid)
503 goto again;
504out:
445 if (*nr_to_scan == 0)
446 break;
447 if (need_resched() || spin_needbreak(&journal->j_list_lock))
448 break;
449 } while (transaction != last_transaction);
450
451 if (transaction != last_transaction) {
452 journal->j_shrink_transaction = next_transaction;

--- 4 unchanged lines hidden (view full) ---

457 }
458
459 spin_unlock(&journal->j_list_lock);
460 cond_resched();
461
462 if (*nr_to_scan && next_tid)
463 goto again;
464out:
505 nr_scanned -= *nr_to_scan;
506 trace_jbd2_shrink_checkpoint_list(journal, first_tid, tid, last_tid,
465 trace_jbd2_shrink_checkpoint_list(journal, first_tid, tid, last_tid,
507 nr_freed, nr_scanned, next_tid);
466 nr_freed, next_tid);
508
509 return nr_freed;
510}
511
512/*
513 * journal_clean_checkpoint_list
514 *
515 * Find all the written-back checkpoint buffers in the journal and release them.
516 * If 'destroy' is set, release all buffers unconditionally.
517 *
518 * Called with j_list_lock held.
519 */
520void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy)
521{
522 transaction_t *transaction, *last_transaction, *next_transaction;
467
468 return nr_freed;
469}
470
471/*
472 * journal_clean_checkpoint_list
473 *
474 * Find all the written-back checkpoint buffers in the journal and release them.
475 * If 'destroy' is set, release all buffers unconditionally.
476 *
477 * Called with j_list_lock held.
478 */
479void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy)
480{
481 transaction_t *transaction, *last_transaction, *next_transaction;
523 int ret;
482 bool released;
524
525 transaction = journal->j_checkpoint_transactions;
526 if (!transaction)
527 return;
528
529 last_transaction = transaction->t_cpprev;
530 next_transaction = transaction;
531 do {
532 transaction = next_transaction;
533 next_transaction = transaction->t_cpnext;
483
484 transaction = journal->j_checkpoint_transactions;
485 if (!transaction)
486 return;
487
488 last_transaction = transaction->t_cpprev;
489 next_transaction = transaction;
490 do {
491 transaction = next_transaction;
492 next_transaction = transaction->t_cpnext;
534 ret = journal_clean_one_cp_list(transaction->t_checkpoint_list,
535 destroy);
493 journal_shrink_one_cp_list(transaction->t_checkpoint_list,
494 destroy, &released);
536 /*
537 * This function only frees up some memory if possible so we
538 * dont have an obligation to finish processing. Bail out if
539 * preemption requested:
540 */
541 if (need_resched())
542 return;
543 /*
544 * Stop scanning if we couldn't free the transaction. This
545 * avoids pointless scanning of transactions which still
546 * weren't checkpointed.
547 */
495 /*
496 * This function only frees up some memory if possible so we
497 * dont have an obligation to finish processing. Bail out if
498 * preemption requested:
499 */
500 if (need_resched())
501 return;
502 /*
503 * Stop scanning if we couldn't free the transaction. This
504 * avoids pointless scanning of transactions which still
505 * weren't checkpointed.
506 */
548 if (!ret)
507 if (!released)
549 return;
550 } while (transaction != last_transaction);
551}
552
553/*
554 * Remove buffers from all checkpoint lists as journal is aborted and we just
555 * need to free memory
556 */

--- 170 unchanged lines hidden ---
508 return;
509 } while (transaction != last_transaction);
510}
511
512/*
513 * Remove buffers from all checkpoint lists as journal is aborted and we just
514 * need to free memory
515 */

--- 170 unchanged lines hidden ---