86 #include <linux/time.h>
89 #include <linux/errno.h>
90 #include <linux/slab.h>
91 #include <linux/list.h>
124 static void write_one_revoke_record(journal_t *,
transaction_t *,
127 static void flush_descriptor(journal_t *,
struct journal_head *,
int,
int);
133 static inline int hash(journal_t *journal,
unsigned int block)
138 return ((block << (hash_shift - 6)) ^
140 (block << (hash_shift - 12))) & (table->
hash_size - 1);
143 static int insert_revoke_hash(journal_t *journal,
unsigned int blocknr,
156 hash_list = &journal->j_revoke->hash_table[
hash(journal, blocknr)];
157 spin_lock(&journal->j_revoke_lock);
158 list_add(&record->
hash, hash_list);
159 spin_unlock(&journal->j_revoke_lock);
165 jbd_debug(1,
"ENOMEM in %s, retrying\n", __func__);
173 unsigned int blocknr)
178 hash_list = &journal->j_revoke->hash_table[
hash(journal, blocknr)];
180 spin_lock(&journal->j_revoke_lock);
182 while (&(record->
hash) != hash_list) {
183 if (record->
blocknr == blocknr) {
184 spin_unlock(&journal->j_revoke_lock);
189 spin_unlock(&journal->j_revoke_lock);
195 if (revoke_record_cache) {
197 revoke_record_cache =
NULL;
199 if (revoke_table_cache) {
201 revoke_table_cache =
NULL;
207 J_ASSERT(!revoke_record_cache);
208 J_ASSERT(!revoke_table_cache);
215 if (!revoke_record_cache)
216 goto record_cache_failure;
221 if (!revoke_table_cache)
222 goto table_cache_failure;
228 record_cache_failure:
242 while((tmp >>= 1
UL) != 0
UL)
269 J_ASSERT(list_empty(hash_list));
279 J_ASSERT(journal->j_revoke_table[0] ==
NULL);
282 journal->j_revoke_table[0] = journal_init_revoke_table(hash_size);
283 if (!journal->j_revoke_table[0])
286 journal->j_revoke_table[1] = journal_init_revoke_table(hash_size);
287 if (!journal->j_revoke_table[1])
290 journal->j_revoke = journal->j_revoke_table[1];
297 journal_destroy_revoke_table(journal->j_revoke_table[0]);
305 journal->j_revoke =
NULL;
306 if (journal->j_revoke_table[0])
307 journal_destroy_revoke_table(journal->j_revoke_table[0]);
308 if (journal->j_revoke_table[1])
309 journal_destroy_revoke_table(journal->j_revoke_table[1]);
339 int journal_revoke(handle_t *
handle,
unsigned int blocknr,
340 struct buffer_head *bh_in)
342 struct buffer_head *bh =
NULL;
349 BUFFER_TRACE(bh_in,
"enter");
351 journal = handle->h_transaction->t_journal;
353 J_ASSERT (!
"Cannot set revoke feature!");
357 bdev = journal->j_fs_dev;
363 BUFFER_TRACE(bh,
"found on hash");
365 #ifdef JBD_EXPENSIVE_CHECKING
367 struct buffer_head *bh2;
374 if (bh2 != bh && buffer_revokevalid(bh2))
381 J_ASSERT_BH(bh2, buffer_revoked(bh2));
391 if (!J_EXPECT_BH(bh, !buffer_revoked(bh),
392 "inconsistent data on disk")) {
397 set_buffer_revoked(bh);
398 set_buffer_revokevalid(bh);
400 BUFFER_TRACE(bh_in,
"call journal_forget");
403 BUFFER_TRACE(bh,
"call brelse");
408 jbd_debug(2,
"insert revoke for block %u, bh_in=%p\n", blocknr, bh_in);
409 err = insert_revoke_hash(journal, blocknr,
410 handle->h_transaction->t_tid);
411 BUFFER_TRACE(bh_in,
"exit");
430 int journal_cancel_revoke(handle_t *handle,
struct journal_head *jh)
433 journal_t *journal = handle->h_transaction->t_journal;
436 struct buffer_head *bh = jh2bh(jh);
438 jbd_debug(4,
"journal_head %p, cancelling revoke\n", jh);
444 if (test_set_buffer_revokevalid(bh)) {
445 need_cancel = test_clear_buffer_revoked(bh);
448 clear_buffer_revoked(bh);
452 record = find_revoke_record(journal, bh->b_blocknr);
454 jbd_debug(4,
"cancelled existing revoke on "
455 "blocknr %llu\n", (
unsigned long long)bh->b_blocknr);
456 spin_lock(&journal->j_revoke_lock);
458 spin_unlock(&journal->j_revoke_lock);
464 #ifdef JBD_EXPENSIVE_CHECKING
466 record = find_revoke_record(journal, bh->b_blocknr);
467 J_ASSERT_JH(jh, record ==
NULL);
475 struct buffer_head *bh2;
479 clear_buffer_revoked(bh2);
491 void journal_clear_buffer_revoked_flags(journal_t *journal)
496 for (i = 0; i < revoke->
hash_size; i++) {
503 struct buffer_head *bh;
507 journal->j_blocksize);
509 clear_buffer_revoked(bh);
520 void journal_switch_revoke_table(journal_t *journal)
524 if (journal->j_revoke == journal->j_revoke_table[0])
525 journal->j_revoke = journal->j_revoke_table[1];
527 journal->j_revoke = journal->j_revoke_table[0];
529 for (i = 0; i < journal->j_revoke->hash_size; i++)
530 INIT_LIST_HEAD(&journal->j_revoke->hash_table[i]);
537 void journal_write_revoke_records(journal_t *journal,
551 revoke = journal->j_revoke == journal->j_revoke_table[0] ?
552 journal->j_revoke_table[1] : journal->j_revoke_table[0];
554 for (i = 0; i < revoke->
hash_size; i++) {
557 while (!list_empty(hash_list)) {
560 write_one_revoke_record(journal, transaction,
561 &descriptor, &offset,
569 flush_descriptor(journal, descriptor, offset, write_op);
570 jbd_debug(1,
"Wrote %d revoke records\n", count);
578 static void write_one_revoke_record(journal_t *journal,
593 if (is_journal_aborted(journal))
596 descriptor = *descriptorp;
601 if (offset == journal->j_blocksize) {
602 flush_descriptor(journal, descriptor, offset, write_op);
617 JBUFFER_TRACE(descriptor,
"file as BJ_LogCtl");
637 static void flush_descriptor(journal_t *journal,
639 int offset,
int write_op)
642 struct buffer_head *bh = jh2bh(descriptor);
644 if (is_journal_aborted(journal)) {
651 set_buffer_jwrite(bh);
652 BUFFER_TRACE(bh,
"write");
653 set_buffer_dirty(bh);
681 unsigned int blocknr,
686 record = find_revoke_record(journal, blocknr);
690 if (tid_gt(sequence, record->
sequence))
694 return insert_revoke_hash(journal, blocknr, sequence);
705 unsigned int blocknr,
710 record = find_revoke_record(journal, blocknr);
713 if (tid_gt(sequence, record->
sequence))
730 revoke = journal->j_revoke;
732 for (i = 0; i < revoke->
hash_size; i++) {
734 while (!list_empty(hash_list)) {