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 --- |