Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }