^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/jbd2/revoke.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by Stephen C. Tweedie <sct@redhat.com>, 2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright 2000 Red Hat corp --- All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Journal revoke routines for the generic filesystem journaling code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * part of the ext2fs journaling system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Revoke is the mechanism used to prevent old log records for deleted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * metadata from being replayed on top of newer data using the same
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * blocks. The revoke mechanism is used in two separate places:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * + Commit: during commit we write the entire list of the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * transaction's revoked blocks to the journal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * + Recovery: during recovery we record the transaction ID of all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * revoked blocks. If there are multiple revoke records in the log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * for a single block, only the last one counts, and if there is a log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * entry for a block beyond the last revoke, then that log entry still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * gets replayed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * We can get interactions between revokes and new log data within a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * single transaction:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Block is revoked and then journaled:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * The desired end result is the journaling of the new block, so we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * cancel the revoke before the transaction commits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * Block is journaled and then revoked:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * The revoke must take precedence over the write of the block, so we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * need either to cancel the journal entry or to write the revoke
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * later in the log than the log block. In this case, we choose the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * latter: journaling a block cancels any revoke record for that block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * in the current transaction, so any revoke for that block in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * transaction must have happened after the block was journaled and so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * the revoke must take precedence.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * Block is revoked and then written as data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * The data write is allowed to succeed, but the revoke is _not_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * cancelled. We still need to prevent old log records from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * overwriting the new data. We don't even need to clear the revoke
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * bit here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * We cache revoke status of a buffer in the current transaction in b_states
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * bits. As the name says, revokevalid flag indicates that the cached revoke
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * status of a buffer is valid and we can rely on the cached status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * Revoke information on buffers is a tri-state value:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * RevokeValid clear: no cached revoke status, need to look it up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * RevokeValid set, Revoked clear:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * buffer has not been revoked, and cancel_revoke
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * need do nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * RevokeValid set, Revoked set:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * buffer has been revoked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * Locking rules:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * We keep two hash tables of revoke records. One hashtable belongs to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * running transaction (is pointed to by journal->j_revoke), the other one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * belongs to the committing transaction. Accesses to the second hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) * happen only from the kjournald and no other thread touches this table. Also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * journal_switch_revoke_table() which switches which hashtable belongs to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * running and which to the committing transaction is called only from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * kjournald. Therefore we need no locks when accessing the hashtable belonging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * to the committing transaction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * All users operating on the hash table belonging to the running transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * have a handle to the transaction. Therefore they are safe from kjournald
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * switching hash tables under them. For operations on the lists of entries in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * the hash table j_revoke_lock is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * Finally, also replay code uses the hash tables but at this moment no one else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * can touch them (filesystem isn't mounted yet) and hence no locking is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #ifndef __KERNEL__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #include "jfs_user.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #include <linux/jbd2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #include <linux/bio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #include <linux/log2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #include <linux/hash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static struct kmem_cache *jbd2_revoke_record_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static struct kmem_cache *jbd2_revoke_table_cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* Each revoke record represents one single revoked block. During
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) journal replay, this involves recording the transaction ID of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) last transaction to revoke this block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct jbd2_revoke_record_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct list_head hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) tid_t sequence; /* Used for recovery only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned long long blocknr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* The revoke table is just a simple hash table of revoke records. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct jbd2_revoke_table_s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* It is conceivable that we might want a larger hash table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * for recovery. Must be a power of two. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int hash_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) int hash_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct list_head *hash_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #ifdef __KERNEL__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static void write_one_revoke_record(transaction_t *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct list_head *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) struct buffer_head **, int *,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct jbd2_revoke_record_s *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static void flush_descriptor(journal_t *, struct buffer_head *, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* Utility functions to maintain the revoke table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static inline int hash(journal_t *journal, unsigned long long block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return hash_64(block, journal->j_revoke->hash_shift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static int insert_revoke_hash(journal_t *journal, unsigned long long blocknr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) tid_t seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct list_head *hash_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct jbd2_revoke_record_s *record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) gfp_t gfp_mask = GFP_NOFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (journal_oom_retry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) gfp_mask |= __GFP_NOFAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) record = kmem_cache_alloc(jbd2_revoke_record_cache, gfp_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (!record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) record->sequence = seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) record->blocknr = blocknr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) spin_lock(&journal->j_revoke_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) list_add(&record->hash, hash_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) spin_unlock(&journal->j_revoke_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* Find a revoke record in the journal's hash table. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static struct jbd2_revoke_record_s *find_revoke_record(journal_t *journal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) unsigned long long blocknr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct list_head *hash_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct jbd2_revoke_record_s *record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) spin_lock(&journal->j_revoke_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) record = (struct jbd2_revoke_record_s *) hash_list->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) while (&(record->hash) != hash_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (record->blocknr == blocknr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) spin_unlock(&journal->j_revoke_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) record = (struct jbd2_revoke_record_s *) record->hash.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) spin_unlock(&journal->j_revoke_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) void jbd2_journal_destroy_revoke_record_cache(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) kmem_cache_destroy(jbd2_revoke_record_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) jbd2_revoke_record_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) void jbd2_journal_destroy_revoke_table_cache(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) kmem_cache_destroy(jbd2_revoke_table_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) jbd2_revoke_table_cache = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int __init jbd2_journal_init_revoke_record_cache(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) J_ASSERT(!jbd2_revoke_record_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) jbd2_revoke_record_cache = KMEM_CACHE(jbd2_revoke_record_s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (!jbd2_revoke_record_cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) pr_emerg("JBD2: failed to create revoke_record cache\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int __init jbd2_journal_init_revoke_table_cache(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) J_ASSERT(!jbd2_revoke_table_cache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) jbd2_revoke_table_cache = KMEM_CACHE(jbd2_revoke_table_s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) SLAB_TEMPORARY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (!jbd2_revoke_table_cache) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) pr_emerg("JBD2: failed to create revoke_table cache\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static struct jbd2_revoke_table_s *jbd2_journal_init_revoke_table(int hash_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) int shift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) int tmp = hash_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct jbd2_revoke_table_s *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) table = kmem_cache_alloc(jbd2_revoke_table_cache, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (!table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) while((tmp >>= 1UL) != 0UL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) shift++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) table->hash_size = hash_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) table->hash_shift = shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) table->hash_table =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) kmalloc_array(hash_size, sizeof(struct list_head), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (!table->hash_table) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) kmem_cache_free(jbd2_revoke_table_cache, table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) table = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) for (tmp = 0; tmp < hash_size; tmp++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) INIT_LIST_HEAD(&table->hash_table[tmp]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static void jbd2_journal_destroy_revoke_table(struct jbd2_revoke_table_s *table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct list_head *hash_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) for (i = 0; i < table->hash_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) hash_list = &table->hash_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) J_ASSERT(list_empty(hash_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) kfree(table->hash_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) kmem_cache_free(jbd2_revoke_table_cache, table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* Initialise the revoke table for a given journal to a given size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) int jbd2_journal_init_revoke(journal_t *journal, int hash_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) J_ASSERT(journal->j_revoke_table[0] == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) J_ASSERT(is_power_of_2(hash_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) journal->j_revoke_table[0] = jbd2_journal_init_revoke_table(hash_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (!journal->j_revoke_table[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) goto fail0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) journal->j_revoke_table[1] = jbd2_journal_init_revoke_table(hash_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (!journal->j_revoke_table[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) goto fail1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) journal->j_revoke = journal->j_revoke_table[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) spin_lock_init(&journal->j_revoke_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) fail1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) jbd2_journal_destroy_revoke_table(journal->j_revoke_table[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) journal->j_revoke_table[0] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) fail0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /* Destroy a journal's revoke table. The table must already be empty! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) void jbd2_journal_destroy_revoke(journal_t *journal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) journal->j_revoke = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (journal->j_revoke_table[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) jbd2_journal_destroy_revoke_table(journal->j_revoke_table[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (journal->j_revoke_table[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) jbd2_journal_destroy_revoke_table(journal->j_revoke_table[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) #ifdef __KERNEL__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * jbd2_journal_revoke: revoke a given buffer_head from the journal. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * prevents the block from being replayed during recovery if we take a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * crash after this current transaction commits. Any subsequent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * metadata writes of the buffer in this transaction cancel the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * revoke.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * Note that this call may block --- it is up to the caller to make
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * sure that there are no further calls to journal_write_metadata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * before the revoke is complete. In ext3, this implies calling the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * revoke before clearing the block bitmap when we are deleting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * metadata.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * Revoke performs a jbd2_journal_forget on any buffer_head passed in as a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * parameter, but does _not_ forget the buffer_head if the bh was only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * found implicitly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * bh_in may not be a journalled buffer - it may have come off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * the hash tables without an attached journal_head.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * If bh_in is non-zero, jbd2_journal_revoke() will decrement its b_count
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * by one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) int jbd2_journal_revoke(handle_t *handle, unsigned long long blocknr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct buffer_head *bh_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct buffer_head *bh = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) journal_t *journal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct block_device *bdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) might_sleep();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (bh_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) BUFFER_TRACE(bh_in, "enter");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) journal = handle->h_transaction->t_journal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (!jbd2_journal_set_features(journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) J_ASSERT (!"Cannot set revoke feature!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) bdev = journal->j_fs_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) bh = bh_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (!bh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) bh = __find_get_block(bdev, blocknr, journal->j_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) BUFFER_TRACE(bh, "found on hash");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) #ifdef JBD2_EXPENSIVE_CHECKING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct buffer_head *bh2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) /* If there is a different buffer_head lying around in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * memory anywhere... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) bh2 = __find_get_block(bdev, blocknr, journal->j_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (bh2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* ... and it has RevokeValid status... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (bh2 != bh && buffer_revokevalid(bh2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* ...then it better be revoked too,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * since it's illegal to create a revoke
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * record against a buffer_head which is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * not marked revoked --- that would
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * risk missing a subsequent revoke
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * cancel. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) J_ASSERT_BH(bh2, buffer_revoked(bh2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) put_bh(bh2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (WARN_ON_ONCE(handle->h_revoke_credits <= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (!bh_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /* We really ought not ever to revoke twice in a row without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) first having the revoke cancelled: it's illegal to free a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) block twice without allocating it in between! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (bh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (!J_EXPECT_BH(bh, !buffer_revoked(bh),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) "inconsistent data on disk")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (!bh_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) set_buffer_revoked(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) set_buffer_revokevalid(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (bh_in) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) BUFFER_TRACE(bh_in, "call jbd2_journal_forget");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) jbd2_journal_forget(handle, bh_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) BUFFER_TRACE(bh, "call brelse");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) __brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) handle->h_revoke_credits--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) jbd_debug(2, "insert revoke for block %llu, bh_in=%p\n",blocknr, bh_in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) err = insert_revoke_hash(journal, blocknr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) handle->h_transaction->t_tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) BUFFER_TRACE(bh_in, "exit");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * Cancel an outstanding revoke. For use only internally by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * journaling code (called from jbd2_journal_get_write_access).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) * We trust buffer_revoked() on the buffer if the buffer is already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * being journaled: if there is no revoke pending on the buffer, then we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) * don't do anything here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * This would break if it were possible for a buffer to be revoked and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * discarded, and then reallocated within the same transaction. In such
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) * a case we would have lost the revoked bit, but when we arrived here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * the second time we would still have a pending revoke to cancel. So,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * do not trust the Revoked bit on buffers unless RevokeValid is also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) int jbd2_journal_cancel_revoke(handle_t *handle, struct journal_head *jh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct jbd2_revoke_record_s *record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) journal_t *journal = handle->h_transaction->t_journal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) int need_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) int did_revoke = 0; /* akpm: debug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct buffer_head *bh = jh2bh(jh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) jbd_debug(4, "journal_head %p, cancelling revoke\n", jh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) /* Is the existing Revoke bit valid? If so, we trust it, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * only perform the full cancel if the revoke bit is set. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * not, we can't trust the revoke bit, and we need to do the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * full search for a revoke record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (test_set_buffer_revokevalid(bh)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) need_cancel = test_clear_buffer_revoked(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) need_cancel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) clear_buffer_revoked(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (need_cancel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) record = find_revoke_record(journal, bh->b_blocknr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (record) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) jbd_debug(4, "cancelled existing revoke on "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) "blocknr %llu\n", (unsigned long long)bh->b_blocknr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) spin_lock(&journal->j_revoke_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) list_del(&record->hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) spin_unlock(&journal->j_revoke_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) kmem_cache_free(jbd2_revoke_record_cache, record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) did_revoke = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) #ifdef JBD2_EXPENSIVE_CHECKING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) /* There better not be one left behind by now! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) record = find_revoke_record(journal, bh->b_blocknr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) J_ASSERT_JH(jh, record == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /* Finally, have we just cleared revoke on an unhashed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * buffer_head? If so, we'd better make sure we clear the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * revoked status on any hashed alias too, otherwise the revoke
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) * state machine will get very upset later on. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) if (need_cancel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct buffer_head *bh2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) bh2 = __find_get_block(bh->b_bdev, bh->b_blocknr, bh->b_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (bh2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (bh2 != bh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) clear_buffer_revoked(bh2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) __brelse(bh2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return did_revoke;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * journal_clear_revoked_flag clears revoked flag of buffers in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * revoke table to reflect there is no revoked buffers in the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * transaction which is going to be started.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) void jbd2_clear_buffer_revoked_flags(journal_t *journal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct jbd2_revoke_table_s *revoke = journal->j_revoke;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) for (i = 0; i < revoke->hash_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) struct list_head *hash_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct list_head *list_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) hash_list = &revoke->hash_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) list_for_each(list_entry, hash_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct jbd2_revoke_record_s *record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) struct buffer_head *bh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) record = (struct jbd2_revoke_record_s *)list_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) bh = __find_get_block(journal->j_fs_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) record->blocknr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) journal->j_blocksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (bh) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) clear_buffer_revoked(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) __brelse(bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /* journal_switch_revoke table select j_revoke for next transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * we do not want to suspend any processing until all revokes are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * written -bzzz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) void jbd2_journal_switch_revoke_table(journal_t *journal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (journal->j_revoke == journal->j_revoke_table[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) journal->j_revoke = journal->j_revoke_table[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) journal->j_revoke = journal->j_revoke_table[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) for (i = 0; i < journal->j_revoke->hash_size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) INIT_LIST_HEAD(&journal->j_revoke->hash_table[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) * Write revoke records to the journal for all entries in the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * revoke hash, deleting the entries as we go.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) void jbd2_journal_write_revoke_records(transaction_t *transaction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct list_head *log_bufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) journal_t *journal = transaction->t_journal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct buffer_head *descriptor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct jbd2_revoke_record_s *record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) struct jbd2_revoke_table_s *revoke;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) struct list_head *hash_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) int i, offset, count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) descriptor = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /* select revoke table for committing transaction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) revoke = journal->j_revoke == journal->j_revoke_table[0] ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) journal->j_revoke_table[1] : journal->j_revoke_table[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) for (i = 0; i < revoke->hash_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) hash_list = &revoke->hash_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) while (!list_empty(hash_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) record = (struct jbd2_revoke_record_s *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) hash_list->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) write_one_revoke_record(transaction, log_bufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) &descriptor, &offset, record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) list_del(&record->hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) kmem_cache_free(jbd2_revoke_record_cache, record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (descriptor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) flush_descriptor(journal, descriptor, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) jbd_debug(1, "Wrote %d revoke records\n", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * Write out one revoke record. We need to create a new descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * block if the old one is full or if we have not already created one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static void write_one_revoke_record(transaction_t *transaction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) struct list_head *log_bufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct buffer_head **descriptorp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) int *offsetp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) struct jbd2_revoke_record_s *record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) journal_t *journal = transaction->t_journal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) int csum_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct buffer_head *descriptor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) int sz, offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /* If we are already aborting, this all becomes a noop. We
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) still need to go round the loop in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) jbd2_journal_write_revoke_records in order to free all of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) revoke records: only the IO to the journal is omitted. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (is_journal_aborted(journal))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) descriptor = *descriptorp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) offset = *offsetp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /* Do we need to leave space at the end for a checksum? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (jbd2_journal_has_csum_v2or3(journal))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) csum_size = sizeof(struct jbd2_journal_block_tail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (jbd2_has_feature_64bit(journal))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) sz = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) sz = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /* Make sure we have a descriptor with space left for the record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (descriptor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (offset + sz > journal->j_blocksize - csum_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) flush_descriptor(journal, descriptor, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) descriptor = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (!descriptor) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) descriptor = jbd2_journal_get_descriptor_buffer(transaction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) JBD2_REVOKE_BLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (!descriptor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) /* Record it so that we can wait for IO completion later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) BUFFER_TRACE(descriptor, "file in log_bufs");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) jbd2_file_log_bh(log_bufs, descriptor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) offset = sizeof(jbd2_journal_revoke_header_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) *descriptorp = descriptor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (jbd2_has_feature_64bit(journal))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * ((__be64 *)(&descriptor->b_data[offset])) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) cpu_to_be64(record->blocknr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * ((__be32 *)(&descriptor->b_data[offset])) =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) cpu_to_be32(record->blocknr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) offset += sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) *offsetp = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * Flush a revoke descriptor out to the journal. If we are aborting,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) * this is a noop; otherwise we are generating a buffer which needs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * be waited for during commit, so it has to go onto the appropriate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) * journal buffer list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) static void flush_descriptor(journal_t *journal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) struct buffer_head *descriptor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) jbd2_journal_revoke_header_t *header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (is_journal_aborted(journal))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) header = (jbd2_journal_revoke_header_t *)descriptor->b_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) header->r_count = cpu_to_be32(offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) jbd2_descriptor_block_csum_set(journal, descriptor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) set_buffer_jwrite(descriptor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) BUFFER_TRACE(descriptor, "write");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) set_buffer_dirty(descriptor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) write_dirty_buffer(descriptor, REQ_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * Revoke support for recovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) * Recovery needs to be able to:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * record all revoke records, including the tid of the latest instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * of each revoke in the journal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) * check whether a given block in a given transaction should be replayed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) * (ie. has not been revoked by a revoke record in that or a subsequent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) * transaction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * empty the revoke table after recovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * First, setting revoke records. We create a new revoke record for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * every block ever revoked in the log as we scan it for recovery, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * we update the existing records if we find multiple revokes for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * single block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) int jbd2_journal_set_revoke(journal_t *journal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) unsigned long long blocknr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) tid_t sequence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct jbd2_revoke_record_s *record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) record = find_revoke_record(journal, blocknr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (record) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /* If we have multiple occurrences, only record the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * latest sequence number in the hashed record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (tid_gt(sequence, record->sequence))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) record->sequence = sequence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) return insert_revoke_hash(journal, blocknr, sequence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * Test revoke records. For a given block referenced in the log, has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * that block been revoked? A revoke record with a given transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * sequence number revokes all blocks in that transaction and earlier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * ones, but later transactions still need replayed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) int jbd2_journal_test_revoke(journal_t *journal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) unsigned long long blocknr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) tid_t sequence)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct jbd2_revoke_record_s *record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) record = find_revoke_record(journal, blocknr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (!record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (tid_gt(sequence, record->sequence))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * Finally, once recovery is over, we need to clear the revoke table so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * that it can be reused by the running filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) void jbd2_journal_clear_revoke(journal_t *journal)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) struct list_head *hash_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) struct jbd2_revoke_record_s *record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct jbd2_revoke_table_s *revoke;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) revoke = journal->j_revoke;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) for (i = 0; i < revoke->hash_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) hash_list = &revoke->hash_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) while (!list_empty(hash_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) record = (struct jbd2_revoke_record_s*) hash_list->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) list_del(&record->hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) kmem_cache_free(jbd2_revoke_record_cache, record);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }