1 Index: linux-3.10.0-1160.80.1.el7/fs/jbd2/recovery.c
2 ===================================================================
3 --- linux-3.10.0-1160.80.1.el7.orig/fs/jbd2/recovery.c
4 +++ linux-3.10.0-1160.80.1.el7/fs/jbd2/recovery.c
6 #include <linux/errno.h>
7 #include <linux/crc32.h>
8 #include <linux/blkdev.h>
9 +#include <linux/rhashtable.h>
13 @@ -255,6 +256,10 @@ int jbd2_journal_recover(journal_t *jour
14 memset(&info, 0, sizeof(info));
15 sb = journal->j_superblock;
17 + err = jbd2_journal_init_recovery_revoke(journal);
22 * The journal superblock's s_start field (the current log head)
23 * is always zero if, and only if, the journal was cleanly
24 Index: linux-3.10.0-1160.80.1.el7/fs/jbd2/revoke.c
25 ===================================================================
26 --- linux-3.10.0-1160.80.1.el7.orig/fs/jbd2/revoke.c
27 +++ linux-3.10.0-1160.80.1.el7/fs/jbd2/revoke.c
29 #include <linux/bio.h>
30 #include <linux/log2.h>
31 #include <linux/hash.h>
32 +#include <linux/rhashtable.h>
35 static struct kmem_cache *jbd2_revoke_record_cache;
36 @@ -104,7 +105,10 @@ static struct kmem_cache *jbd2_revoke_ta
38 struct jbd2_revoke_record_s
40 - struct list_head hash;
42 + struct list_head hash;
43 + struct rhash_head linkage;
45 tid_t sequence; /* Used for recovery only */
46 unsigned long long blocknr;
48 @@ -701,13 +705,21 @@ static void flush_descriptor(journal_t *
52 +static const struct rhashtable_params revoke_rhashtable_params = {
53 + .key_len = sizeof(unsigned long long),
54 + .key_offset = offsetof(struct jbd2_revoke_record_s, blocknr),
55 + .head_offset = offsetof(struct jbd2_revoke_record_s, linkage),
58 int jbd2_journal_set_revoke(journal_t *journal,
59 unsigned long long blocknr,
62 - struct jbd2_revoke_record_s *record;
63 + struct jbd2_revoke_record_s *record, *old;
64 + gfp_t gfp_mask = GFP_NOFS;
66 - record = find_revoke_record(journal, blocknr);
67 + record = rhashtable_lookup(&journal->j_revoke_rhtable, &blocknr,
68 + revoke_rhashtable_params);
70 /* If we have multiple occurrences, only record the
71 * latest sequence number in the hashed record */
72 @@ -715,7 +727,24 @@ int jbd2_journal_set_revoke(journal_t *j
73 record->sequence = sequence;
76 - return insert_revoke_hash(journal, blocknr, sequence);
78 + if (journal_oom_retry)
79 + gfp_mask |= __GFP_NOFAIL;
80 + record = kmem_cache_alloc(jbd2_revoke_record_cache, gfp_mask);
84 + record->sequence = sequence;
85 + record->blocknr = blocknr;
86 + old = rhashtable_lookup_get_insert_fast(&journal->j_revoke_rhtable,
87 + &record->linkage, revoke_rhashtable_params);
89 + kmem_cache_free(jbd2_revoke_record_cache, record);
90 + return PTR_ERR(old);
92 + BUG_ON(old != NULL);
98 @@ -731,7 +760,8 @@ int jbd2_journal_test_revoke(journal_t *
100 struct jbd2_revoke_record_s *record;
102 - record = find_revoke_record(journal, blocknr);
103 + record = rhashtable_lookup(&journal->j_revoke_rhtable, &blocknr,
104 + revoke_rhashtable_params);
107 if (tid_gt(sequence, record->sequence))
108 @@ -739,6 +769,17 @@ int jbd2_journal_test_revoke(journal_t *
112 +int jbd2_journal_init_recovery_revoke(journal_t *journal)
114 + return rhashtable_init(&journal->j_revoke_rhtable,
115 + &revoke_rhashtable_params);
118 +static void jbd2_revoke_record_free(void *ptr, void *arg)
120 + kmem_cache_free(jbd2_revoke_record_cache, ptr);
124 * Finally, once recovery is over, we need to clear the revoke table so
125 * that it can be reused by the running filesystem.
126 @@ -746,19 +787,6 @@ int jbd2_journal_test_revoke(journal_t *
128 void jbd2_journal_clear_revoke(journal_t *journal)
131 - struct list_head *hash_list;
132 - struct jbd2_revoke_record_s *record;
133 - struct jbd2_revoke_table_s *revoke;
135 - revoke = journal->j_revoke;
137 - for (i = 0; i < revoke->hash_size; i++) {
138 - hash_list = &revoke->hash_table[i];
139 - while (!list_empty(hash_list)) {
140 - record = (struct jbd2_revoke_record_s*) hash_list->next;
141 - list_del(&record->hash);
142 - kmem_cache_free(jbd2_revoke_record_cache, record);
145 + rhashtable_free_and_destroy(&journal->j_revoke_rhtable,
146 + jbd2_revoke_record_free, NULL);
148 Index: linux-3.10.0-1160.80.1.el7/include/linux/jbd2.h
149 ===================================================================
150 --- linux-3.10.0-1160.80.1.el7.orig/include/linux/jbd2.h
151 +++ linux-3.10.0-1160.80.1.el7/include/linux/jbd2.h
153 #include <linux/timer.h>
154 #include <linux/slab.h>
155 #include <crypto/hash.h>
156 +#include <linux/rhashtable.h>
159 #define journal_oom_retry 1
160 @@ -944,6 +945,11 @@ struct journal_s
161 struct jbd2_revoke_table_s *j_revoke_table[2];
164 + * rhashtable for revoke records during recovery
166 + struct rhashtable j_revoke_rhtable;
169 * array of bhs for jbd2_journal_commit_transaction
171 struct buffer_head **j_wbuf;
172 @@ -1231,6 +1237,7 @@ extern void jbd2_journal_write_revoke
173 /* Recovery revoke support */
174 extern int jbd2_journal_set_revoke(journal_t *, unsigned long long, tid_t);
175 extern int jbd2_journal_test_revoke(journal_t *, unsigned long long, tid_t);
176 +extern int jbd2_journal_init_recovery_revoke(journal_t *);
177 extern void jbd2_journal_clear_revoke(journal_t *);
178 extern void jbd2_journal_switch_revoke_table(journal_t *journal);
179 extern void jbd2_clear_buffer_revoked_flags(journal_t *journal);