diff options
Diffstat (limited to 'fs/jbd/revoke.c')
| -rw-r--r-- | fs/jbd/revoke.c | 70 |
1 files changed, 35 insertions, 35 deletions
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c index a56144183462..c532429d8d9b 100644 --- a/fs/jbd/revoke.c +++ b/fs/jbd/revoke.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * linux/fs/revoke.c | 2 | * linux/fs/revoke.c |
| 3 | * | 3 | * |
| 4 | * Written by Stephen C. Tweedie <sct@redhat.com>, 2000 | 4 | * Written by Stephen C. Tweedie <sct@redhat.com>, 2000 |
| 5 | * | 5 | * |
| 6 | * Copyright 2000 Red Hat corp --- All Rights Reserved | 6 | * Copyright 2000 Red Hat corp --- All Rights Reserved |
| @@ -15,10 +15,10 @@ | |||
| 15 | * Revoke is the mechanism used to prevent old log records for deleted | 15 | * Revoke is the mechanism used to prevent old log records for deleted |
| 16 | * metadata from being replayed on top of newer data using the same | 16 | * metadata from being replayed on top of newer data using the same |
| 17 | * blocks. The revoke mechanism is used in two separate places: | 17 | * blocks. The revoke mechanism is used in two separate places: |
| 18 | * | 18 | * |
| 19 | * + Commit: during commit we write the entire list of the current | 19 | * + Commit: during commit we write the entire list of the current |
| 20 | * transaction's revoked blocks to the journal | 20 | * transaction's revoked blocks to the journal |
| 21 | * | 21 | * |
| 22 | * + Recovery: during recovery we record the transaction ID of all | 22 | * + Recovery: during recovery we record the transaction ID of all |
| 23 | * revoked blocks. If there are multiple revoke records in the log | 23 | * revoked blocks. If there are multiple revoke records in the log |
| 24 | * for a single block, only the last one counts, and if there is a log | 24 | * for a single block, only the last one counts, and if there is a log |
| @@ -29,7 +29,7 @@ | |||
| 29 | * single transaction: | 29 | * single transaction: |
| 30 | * | 30 | * |
| 31 | * Block is revoked and then journaled: | 31 | * Block is revoked and then journaled: |
| 32 | * The desired end result is the journaling of the new block, so we | 32 | * The desired end result is the journaling of the new block, so we |
| 33 | * cancel the revoke before the transaction commits. | 33 | * cancel the revoke before the transaction commits. |
| 34 | * | 34 | * |
| 35 | * Block is journaled and then revoked: | 35 | * Block is journaled and then revoked: |
| @@ -41,7 +41,7 @@ | |||
| 41 | * transaction must have happened after the block was journaled and so | 41 | * transaction must have happened after the block was journaled and so |
| 42 | * the revoke must take precedence. | 42 | * the revoke must take precedence. |
| 43 | * | 43 | * |
| 44 | * Block is revoked and then written as data: | 44 | * Block is revoked and then written as data: |
| 45 | * The data write is allowed to succeed, but the revoke is _not_ | 45 | * The data write is allowed to succeed, but the revoke is _not_ |
| 46 | * cancelled. We still need to prevent old log records from | 46 | * cancelled. We still need to prevent old log records from |
| 47 | * overwriting the new data. We don't even need to clear the revoke | 47 | * overwriting the new data. We don't even need to clear the revoke |
| @@ -54,7 +54,7 @@ | |||
| 54 | * buffer has not been revoked, and cancel_revoke | 54 | * buffer has not been revoked, and cancel_revoke |
| 55 | * need do nothing. | 55 | * need do nothing. |
| 56 | * RevokeValid set, Revoked set: | 56 | * RevokeValid set, Revoked set: |
| 57 | * buffer has been revoked. | 57 | * buffer has been revoked. |
| 58 | */ | 58 | */ |
| 59 | 59 | ||
| 60 | #ifndef __KERNEL__ | 60 | #ifndef __KERNEL__ |
| @@ -77,7 +77,7 @@ static kmem_cache_t *revoke_table_cache; | |||
| 77 | journal replay, this involves recording the transaction ID of the | 77 | journal replay, this involves recording the transaction ID of the |
| 78 | last transaction to revoke this block. */ | 78 | last transaction to revoke this block. */ |
| 79 | 79 | ||
| 80 | struct jbd_revoke_record_s | 80 | struct jbd_revoke_record_s |
| 81 | { | 81 | { |
| 82 | struct list_head hash; | 82 | struct list_head hash; |
| 83 | tid_t sequence; /* Used for recovery only */ | 83 | tid_t sequence; /* Used for recovery only */ |
| @@ -90,8 +90,8 @@ struct jbd_revoke_table_s | |||
| 90 | { | 90 | { |
| 91 | /* It is conceivable that we might want a larger hash table | 91 | /* It is conceivable that we might want a larger hash table |
| 92 | * for recovery. Must be a power of two. */ | 92 | * for recovery. Must be a power of two. */ |
| 93 | int hash_size; | 93 | int hash_size; |
| 94 | int hash_shift; | 94 | int hash_shift; |
| 95 | struct list_head *hash_table; | 95 | struct list_head *hash_table; |
| 96 | }; | 96 | }; |
| 97 | 97 | ||
| @@ -301,22 +301,22 @@ void journal_destroy_revoke(journal_t *journal) | |||
| 301 | 301 | ||
| 302 | #ifdef __KERNEL__ | 302 | #ifdef __KERNEL__ |
| 303 | 303 | ||
| 304 | /* | 304 | /* |
| 305 | * journal_revoke: revoke a given buffer_head from the journal. This | 305 | * journal_revoke: revoke a given buffer_head from the journal. This |
| 306 | * prevents the block from being replayed during recovery if we take a | 306 | * prevents the block from being replayed during recovery if we take a |
| 307 | * crash after this current transaction commits. Any subsequent | 307 | * crash after this current transaction commits. Any subsequent |
| 308 | * metadata writes of the buffer in this transaction cancel the | 308 | * metadata writes of the buffer in this transaction cancel the |
| 309 | * revoke. | 309 | * revoke. |
| 310 | * | 310 | * |
| 311 | * Note that this call may block --- it is up to the caller to make | 311 | * Note that this call may block --- it is up to the caller to make |
| 312 | * sure that there are no further calls to journal_write_metadata | 312 | * sure that there are no further calls to journal_write_metadata |
| 313 | * before the revoke is complete. In ext3, this implies calling the | 313 | * before the revoke is complete. In ext3, this implies calling the |
| 314 | * revoke before clearing the block bitmap when we are deleting | 314 | * revoke before clearing the block bitmap when we are deleting |
| 315 | * metadata. | 315 | * metadata. |
| 316 | * | 316 | * |
| 317 | * Revoke performs a journal_forget on any buffer_head passed in as a | 317 | * Revoke performs a journal_forget on any buffer_head passed in as a |
| 318 | * parameter, but does _not_ forget the buffer_head if the bh was only | 318 | * parameter, but does _not_ forget the buffer_head if the bh was only |
| 319 | * found implicitly. | 319 | * found implicitly. |
| 320 | * | 320 | * |
| 321 | * bh_in may not be a journalled buffer - it may have come off | 321 | * bh_in may not be a journalled buffer - it may have come off |
| 322 | * the hash tables without an attached journal_head. | 322 | * the hash tables without an attached journal_head. |
| @@ -325,7 +325,7 @@ void journal_destroy_revoke(journal_t *journal) | |||
| 325 | * by one. | 325 | * by one. |
| 326 | */ | 326 | */ |
| 327 | 327 | ||
| 328 | int journal_revoke(handle_t *handle, unsigned long blocknr, | 328 | int journal_revoke(handle_t *handle, unsigned long blocknr, |
| 329 | struct buffer_head *bh_in) | 329 | struct buffer_head *bh_in) |
| 330 | { | 330 | { |
| 331 | struct buffer_head *bh = NULL; | 331 | struct buffer_head *bh = NULL; |
| @@ -487,7 +487,7 @@ void journal_switch_revoke_table(journal_t *journal) | |||
| 487 | else | 487 | else |
| 488 | journal->j_revoke = journal->j_revoke_table[0]; | 488 | journal->j_revoke = journal->j_revoke_table[0]; |
| 489 | 489 | ||
| 490 | for (i = 0; i < journal->j_revoke->hash_size; i++) | 490 | for (i = 0; i < journal->j_revoke->hash_size; i++) |
| 491 | INIT_LIST_HEAD(&journal->j_revoke->hash_table[i]); | 491 | INIT_LIST_HEAD(&journal->j_revoke->hash_table[i]); |
| 492 | } | 492 | } |
| 493 | 493 | ||
| @@ -498,7 +498,7 @@ void journal_switch_revoke_table(journal_t *journal) | |||
| 498 | * Called with the journal lock held. | 498 | * Called with the journal lock held. |
| 499 | */ | 499 | */ |
| 500 | 500 | ||
| 501 | void journal_write_revoke_records(journal_t *journal, | 501 | void journal_write_revoke_records(journal_t *journal, |
| 502 | transaction_t *transaction) | 502 | transaction_t *transaction) |
| 503 | { | 503 | { |
| 504 | struct journal_head *descriptor; | 504 | struct journal_head *descriptor; |
| @@ -507,7 +507,7 @@ void journal_write_revoke_records(journal_t *journal, | |||
| 507 | struct list_head *hash_list; | 507 | struct list_head *hash_list; |
| 508 | int i, offset, count; | 508 | int i, offset, count; |
| 509 | 509 | ||
| 510 | descriptor = NULL; | 510 | descriptor = NULL; |
| 511 | offset = 0; | 511 | offset = 0; |
| 512 | count = 0; | 512 | count = 0; |
| 513 | 513 | ||
| @@ -519,10 +519,10 @@ void journal_write_revoke_records(journal_t *journal, | |||
| 519 | hash_list = &revoke->hash_table[i]; | 519 | hash_list = &revoke->hash_table[i]; |
| 520 | 520 | ||
| 521 | while (!list_empty(hash_list)) { | 521 | while (!list_empty(hash_list)) { |
| 522 | record = (struct jbd_revoke_record_s *) | 522 | record = (struct jbd_revoke_record_s *) |
| 523 | hash_list->next; | 523 | hash_list->next; |
| 524 | write_one_revoke_record(journal, transaction, | 524 | write_one_revoke_record(journal, transaction, |
| 525 | &descriptor, &offset, | 525 | &descriptor, &offset, |
| 526 | record); | 526 | record); |
| 527 | count++; | 527 | count++; |
| 528 | list_del(&record->hash); | 528 | list_del(&record->hash); |
| @@ -534,14 +534,14 @@ void journal_write_revoke_records(journal_t *journal, | |||
| 534 | jbd_debug(1, "Wrote %d revoke records\n", count); | 534 | jbd_debug(1, "Wrote %d revoke records\n", count); |
| 535 | } | 535 | } |
| 536 | 536 | ||
| 537 | /* | 537 | /* |
| 538 | * Write out one revoke record. We need to create a new descriptor | 538 | * Write out one revoke record. We need to create a new descriptor |
| 539 | * block if the old one is full or if we have not already created one. | 539 | * block if the old one is full or if we have not already created one. |
| 540 | */ | 540 | */ |
| 541 | 541 | ||
| 542 | static void write_one_revoke_record(journal_t *journal, | 542 | static void write_one_revoke_record(journal_t *journal, |
| 543 | transaction_t *transaction, | 543 | transaction_t *transaction, |
| 544 | struct journal_head **descriptorp, | 544 | struct journal_head **descriptorp, |
| 545 | int *offsetp, | 545 | int *offsetp, |
| 546 | struct jbd_revoke_record_s *record) | 546 | struct jbd_revoke_record_s *record) |
| 547 | { | 547 | { |
| @@ -584,21 +584,21 @@ static void write_one_revoke_record(journal_t *journal, | |||
| 584 | *descriptorp = descriptor; | 584 | *descriptorp = descriptor; |
| 585 | } | 585 | } |
| 586 | 586 | ||
| 587 | * ((__be32 *)(&jh2bh(descriptor)->b_data[offset])) = | 587 | * ((__be32 *)(&jh2bh(descriptor)->b_data[offset])) = |
| 588 | cpu_to_be32(record->blocknr); | 588 | cpu_to_be32(record->blocknr); |
| 589 | offset += 4; | 589 | offset += 4; |
| 590 | *offsetp = offset; | 590 | *offsetp = offset; |
| 591 | } | 591 | } |
| 592 | 592 | ||
| 593 | /* | 593 | /* |
| 594 | * Flush a revoke descriptor out to the journal. If we are aborting, | 594 | * Flush a revoke descriptor out to the journal. If we are aborting, |
| 595 | * this is a noop; otherwise we are generating a buffer which needs to | 595 | * this is a noop; otherwise we are generating a buffer which needs to |
| 596 | * be waited for during commit, so it has to go onto the appropriate | 596 | * be waited for during commit, so it has to go onto the appropriate |
| 597 | * journal buffer list. | 597 | * journal buffer list. |
| 598 | */ | 598 | */ |
| 599 | 599 | ||
| 600 | static void flush_descriptor(journal_t *journal, | 600 | static void flush_descriptor(journal_t *journal, |
| 601 | struct journal_head *descriptor, | 601 | struct journal_head *descriptor, |
| 602 | int offset) | 602 | int offset) |
| 603 | { | 603 | { |
| 604 | journal_revoke_header_t *header; | 604 | journal_revoke_header_t *header; |
| @@ -618,7 +618,7 @@ static void flush_descriptor(journal_t *journal, | |||
| 618 | } | 618 | } |
| 619 | #endif | 619 | #endif |
| 620 | 620 | ||
| 621 | /* | 621 | /* |
| 622 | * Revoke support for recovery. | 622 | * Revoke support for recovery. |
| 623 | * | 623 | * |
| 624 | * Recovery needs to be able to: | 624 | * Recovery needs to be able to: |
| @@ -629,7 +629,7 @@ static void flush_descriptor(journal_t *journal, | |||
| 629 | * check whether a given block in a given transaction should be replayed | 629 | * check whether a given block in a given transaction should be replayed |
| 630 | * (ie. has not been revoked by a revoke record in that or a subsequent | 630 | * (ie. has not been revoked by a revoke record in that or a subsequent |
| 631 | * transaction) | 631 | * transaction) |
| 632 | * | 632 | * |
| 633 | * empty the revoke table after recovery. | 633 | * empty the revoke table after recovery. |
| 634 | */ | 634 | */ |
| 635 | 635 | ||
| @@ -637,11 +637,11 @@ static void flush_descriptor(journal_t *journal, | |||
| 637 | * First, setting revoke records. We create a new revoke record for | 637 | * First, setting revoke records. We create a new revoke record for |
| 638 | * every block ever revoked in the log as we scan it for recovery, and | 638 | * every block ever revoked in the log as we scan it for recovery, and |
| 639 | * we update the existing records if we find multiple revokes for a | 639 | * we update the existing records if we find multiple revokes for a |
| 640 | * single block. | 640 | * single block. |
| 641 | */ | 641 | */ |
| 642 | 642 | ||
| 643 | int journal_set_revoke(journal_t *journal, | 643 | int journal_set_revoke(journal_t *journal, |
| 644 | unsigned long blocknr, | 644 | unsigned long blocknr, |
| 645 | tid_t sequence) | 645 | tid_t sequence) |
| 646 | { | 646 | { |
| 647 | struct jbd_revoke_record_s *record; | 647 | struct jbd_revoke_record_s *record; |
| @@ -653,18 +653,18 @@ int journal_set_revoke(journal_t *journal, | |||
| 653 | if (tid_gt(sequence, record->sequence)) | 653 | if (tid_gt(sequence, record->sequence)) |
| 654 | record->sequence = sequence; | 654 | record->sequence = sequence; |
| 655 | return 0; | 655 | return 0; |
| 656 | } | 656 | } |
| 657 | return insert_revoke_hash(journal, blocknr, sequence); | 657 | return insert_revoke_hash(journal, blocknr, sequence); |
| 658 | } | 658 | } |
| 659 | 659 | ||
| 660 | /* | 660 | /* |
| 661 | * Test revoke records. For a given block referenced in the log, has | 661 | * Test revoke records. For a given block referenced in the log, has |
| 662 | * that block been revoked? A revoke record with a given transaction | 662 | * that block been revoked? A revoke record with a given transaction |
| 663 | * sequence number revokes all blocks in that transaction and earlier | 663 | * sequence number revokes all blocks in that transaction and earlier |
| 664 | * ones, but later transactions still need replayed. | 664 | * ones, but later transactions still need replayed. |
| 665 | */ | 665 | */ |
| 666 | 666 | ||
| 667 | int journal_test_revoke(journal_t *journal, | 667 | int journal_test_revoke(journal_t *journal, |
| 668 | unsigned long blocknr, | 668 | unsigned long blocknr, |
| 669 | tid_t sequence) | 669 | tid_t sequence) |
| 670 | { | 670 | { |
