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