ReactOS  0.4.14-dev-57-g333b8f1
revoke.c
Go to the documentation of this file.
1 /*
2  * linux/fs/jbd/revoke.c
3  *
4  * Written by Stephen C. Tweedie <sct@redhat.com>, 2000
5  *
6  * Copyright 2000 Red Hat corp --- All Rights Reserved
7  *
8  * This file is part of the Linux kernel and is made available under
9  * the terms of the GNU General Public License, version 2, or at your
10  * option, any later version, incorporated herein by reference.
11  *
12  * Journal revoke routines for the generic filesystem journaling code;
13  * part of the ext2fs journaling system.
14  *
15  * Revoke is the mechanism used to prevent old log records for deleted
16  * metadata from being replayed on top of newer data using the same
17  * blocks. The revoke mechanism is used in two separate places:
18  *
19  * + Commit: during commit we write the entire list of the current
20  * transaction's revoked blocks to the journal
21  *
22  * + Recovery: during recovery we record the transaction ID of all
23  * revoked blocks. If there are multiple revoke records in the log
24  * for a single block, only the last one counts, and if there is a log
25  * entry for a block beyond the last revoke, then that log entry still
26  * gets replayed.
27  *
28  * We can get interactions between revokes and new log data within a
29  * single transaction:
30  *
31  * Block is revoked and then journaled:
32  * The desired end result is the journaling of the new block, so we
33  * cancel the revoke before the transaction commits.
34  *
35  * Block is journaled and then revoked:
36  * The revoke must take precedence over the write of the block, so we
37  * need either to cancel the journal entry or to write the revoke
38  * later in the log than the log block. In this case, we choose the
39  * latter: journaling a block cancels any revoke record for that block
40  * in the current transaction, so any revoke for that block in the
41  * transaction must have happened after the block was journaled and so
42  * the revoke must take precedence.
43  *
44  * Block is revoked and then written as data:
45  * The data write is allowed to succeed, but the revoke is _not_
46  * cancelled. We still need to prevent old log records from
47  * overwriting the new data. We don't even need to clear the revoke
48  * bit here.
49  *
50  * Revoke information on buffers is a tri-state value:
51  *
52  * RevokeValid clear: no cached revoke status, need to look it up
53  * RevokeValid set, Revoked clear:
54  * buffer has not been revoked, and cancel_revoke
55  * need do nothing.
56  * RevokeValid set, Revoked set:
57  * buffer has been revoked.
58  */
59 
60 #ifndef __KERNEL__
61 #include "jfs_user.h"
62 #else
63 #include <linux/time.h>
64 #include <linux/fs.h>
65 #include <linux/jbd.h>
66 #include <linux/errno.h>
67 #include <linux/slab.h>
68 #include <linux/list.h>
69 #include <linux/init.h>
70 #endif
71 #include <linux/log2.h>
72 
75 
76 /* Each revoke record represents one single revoked block. During
77  journal replay, this involves recording the transaction ID of the
78  last transaction to revoke this block. */
79 
81 {
82  struct list_head hash;
83  tid_t sequence; /* Used for recovery only */
84  unsigned long blocknr;
85 };
86 
87 
88 /* The revoke table is just a simple hash table of revoke records. */
90 {
91  /* It is conceivable that we might want a larger hash table
92  * for recovery. Must be a power of two. */
93  int hash_size;
96 };
97 
98 
99 #ifdef __KERNEL__
100 static void write_one_revoke_record(journal_t *, transaction_t *,
101  struct journal_head **, int *,
102  struct jbd_revoke_record_s *);
103 static void flush_descriptor(journal_t *, struct journal_head *, int);
104 #endif
105 
106 /* Utility functions to maintain the revoke table */
107 
108 /* Borrowed from buffer.c: this is a tried and tested block hash function */
109 static inline int hash(journal_t *journal, unsigned long block)
110 {
111  struct jbd_revoke_table_s *table = journal->j_revoke;
112  int hash_shift = table->hash_shift;
113 
114  return ((block << (hash_shift - 6)) ^
115  (block >> 13) ^
116  (block << (hash_shift - 12))) & (table->hash_size - 1);
117 }
118 
119 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
120  tid_t seq)
121 {
122  struct list_head *hash_list;
123  struct jbd_revoke_record_s *record;
124 
125 repeat:
126  record = (struct jbd_revoke_record_s *)
128  if (!record)
129  goto oom;
130 
131  record->sequence = seq;
132  record->blocknr = blocknr;
133  hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
134  jbd_lock(&journal->j_revoke_lock);
135  list_add(&record->hash, hash_list);
136  jbd_unlock(&journal->j_revoke_lock);
137  return 0;
138 
139 oom:
140  if (!journal_oom_retry)
141  return -ENOMEM;
142  jbd_debug(1, "ENOMEM in %s, retrying\n", __FUNCTION__);
143  yield();
144  goto repeat;
145 }
146 
147 /* Find a revoke record in the journal's hash table. */
148 
149 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
150  unsigned long blocknr)
151 {
152  struct list_head *hash_list;
153  struct jbd_revoke_record_s *record;
154 
155  hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
156 
157  jbd_lock(&journal->j_revoke_lock);
158  record = (struct jbd_revoke_record_s *) hash_list->next;
159  while (&(record->hash) != hash_list) {
160  if (record->blocknr == blocknr) {
161  jbd_unlock(&journal->j_revoke_lock);
162  return record;
163  }
164  record = (struct jbd_revoke_record_s *) record->hash.next;
165  }
166  jbd_unlock(&journal->j_revoke_lock);
167  return NULL;
168 }
169 
171 {
172  revoke_record_cache = kmem_cache_create("revoke_record",
173  sizeof(struct jbd_revoke_record_s),
174  0,
176  NULL);
177  if (revoke_record_cache == 0)
178  return -ENOMEM;
179 
180  revoke_table_cache = kmem_cache_create("revoke_table",
181  sizeof(struct jbd_revoke_table_s),
182  0, SLAB_TEMPORARY, NULL);
183  if (revoke_table_cache == 0) {
186  return -ENOMEM;
187  }
188  return 0;
189 }
190 
192 {
197 }
198 
199 /* Initialise the revoke table for a given journal to a given size. */
200 
201 int journal_init_revoke(journal_t *journal, int hash_size)
202 {
203  int shift, tmp;
204 
205  J_ASSERT (journal->j_revoke_table[0] == NULL);
206 
207  shift = 0;
208  tmp = hash_size;
209  while ((tmp >>= 1UL) != 0UL)
210  shift++;
211 
212  journal->j_revoke_table[0] = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
213  if (!journal->j_revoke_table[0])
214  return -ENOMEM;
215  journal->j_revoke = journal->j_revoke_table[0];
216 
217  /* Check that the hash_size is a power of two */
218  J_ASSERT(is_power_of_2(hash_size));
219 
220  journal->j_revoke->hash_size = hash_size;
221 
222  journal->j_revoke->hash_shift = shift;
223 
224  journal->j_revoke->hash_table =
225  kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL);
226  if (!journal->j_revoke->hash_table) {
227  kmem_cache_free(revoke_table_cache, journal->j_revoke_table[0]);
228  journal->j_revoke = NULL;
229  return -ENOMEM;
230  }
231 
232  for (tmp = 0; tmp < hash_size; tmp++)
233  INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
234 
235  journal->j_revoke_table[1] = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
236  if (!journal->j_revoke_table[1]) {
237  kfree(journal->j_revoke_table[0]->hash_table);
238  kmem_cache_free(revoke_table_cache, journal->j_revoke_table[0]);
239  return -ENOMEM;
240  }
241 
242  journal->j_revoke = journal->j_revoke_table[1];
243 
244  /* Check that the hash_size is a power of two */
245  J_ASSERT(is_power_of_2(hash_size));
246 
247  journal->j_revoke->hash_size = hash_size;
248 
249  journal->j_revoke->hash_shift = shift;
250 
251  journal->j_revoke->hash_table =
252  kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL);
253  if (!journal->j_revoke->hash_table) {
254  kfree(journal->j_revoke_table[0]->hash_table);
255  kmem_cache_free(revoke_table_cache, journal->j_revoke_table[0]);
256  kmem_cache_free(revoke_table_cache, journal->j_revoke_table[1]);
257  journal->j_revoke = NULL;
258  return -ENOMEM;
259  }
260 
261  for (tmp = 0; tmp < hash_size; tmp++)
262  INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
263 
264  jbd_lock_init(&journal->j_revoke_lock);
265 
266  return 0;
267 }
268 
269 /* Destoy a journal's revoke table. The table must already be empty! */
270 
271 void journal_destroy_revoke(journal_t *journal)
272 {
273  struct jbd_revoke_table_s *table;
274  struct list_head *hash_list;
275  int i;
276 
277  table = journal->j_revoke_table[0];
278  if (!table)
279  return;
280 
281  for (i=0; i<table->hash_size; i++) {
282  hash_list = &table->hash_table[i];
283  J_ASSERT (list_empty(hash_list));
284  }
285 
286  kfree(table->hash_table);
288  journal->j_revoke = NULL;
289 
290  table = journal->j_revoke_table[1];
291  if (!table)
292  return;
293 
294  for (i=0; i<table->hash_size; i++) {
295  hash_list = &table->hash_table[i];
296  J_ASSERT (list_empty(hash_list));
297  }
298 
299  kfree(table->hash_table);
301  journal->j_revoke = NULL;
302 }
303 
304 
305 #ifdef __KERNEL__
306 
307 /*
308  * journal_revoke: revoke a given buffer_head from the journal. This
309  * prevents the block from being replayed during recovery if we take a
310  * crash after this current transaction commits. Any subsequent
311  * metadata writes of the buffer in this transaction cancel the
312  * revoke.
313  *
314  * Note that this call may block --- it is up to the caller to make
315  * sure that there are no further calls to journal_write_metadata
316  * before the revoke is complete. In ext3, this implies calling the
317  * revoke before clearing the block bitmap when we are deleting
318  * metadata.
319  *
320  * Revoke performs a journal_forget on any buffer_head passed in as a
321  * parameter, but does _not_ forget the buffer_head if the bh was only
322  * found implicitly.
323  *
324  * bh_in may not be a journalled buffer - it may have come off
325  * the hash tables without an attached journal_head.
326  *
327  * If bh_in is non-zero, journal_revoke() will decrement its b_count
328  * by one.
329  */
330 
331 int journal_revoke(handle_t *handle, unsigned long blocknr,
332  struct buffer_head *bh_in)
333 {
334  struct buffer_head *bh = NULL;
335  journal_t *journal;
336  struct block_device *bdev;
337  int err;
338 
339  might_sleep();
340  if (bh_in)
341  BUFFER_TRACE(bh_in, "enter");
342 
343  journal = handle->h_transaction->t_journal;
344  if (!journal_set_features(journal, 0, 0, JFS_FEATURE_INCOMPAT_REVOKE)) {
345  J_ASSERT (!"Cannot set revoke feature!");
346  return -EINVAL;
347  }
348 
349  bdev = journal->j_fs_dev;
350  bh = bh_in;
351 
352  if (!bh) {
353  bh = __find_get_block(bdev, blocknr, journal->j_blocksize);
354  if (bh)
355  BUFFER_TRACE(bh, "found on hash");
356  }
357 #ifdef JBD_EXPENSIVE_CHECKING
358  else {
359  struct buffer_head *bh2;
360 
361  /* If there is a different buffer_head lying around in
362  * memory anywhere... */
363  bh2 = __find_get_block(bdev, blocknr, journal->j_blocksize);
364  if (bh2) {
365  /* ... and it has RevokeValid status... */
366  if (bh2 != bh && buffer_revokevalid(bh2))
367  /* ...then it better be revoked too,
368  * since it's illegal to create a revoke
369  * record against a buffer_head which is
370  * not marked revoked --- that would
371  * risk missing a subsequent revoke
372  * cancel. */
373  J_ASSERT_BH(bh2, buffer_revoked(bh2));
374  put_bh(bh2);
375  }
376  }
377 #endif
378 
379  /* We really ought not ever to revoke twice in a row without
380  first having the revoke cancelled: it's illegal to free a
381  block twice without allocating it in between! */
382  if (bh) {
383  if (!J_EXPECT_BH(bh, !buffer_revoked(bh),
384  "inconsistent data on disk")) {
385  if (!bh_in)
386  brelse(bh);
387  return -EIO;
388  }
389  set_buffer_revoked(bh);
390  set_buffer_revokevalid(bh);
391  if (bh_in) {
392  BUFFER_TRACE(bh_in, "call journal_forget");
393  journal_forget(handle, bh_in);
394  } else {
395  BUFFER_TRACE(bh, "call brelse");
396  __brelse(bh);
397  }
398  }
399 
400  jbd_debug(2, "insert revoke for block %lu, bh_in=%p\n", blocknr, bh_in);
401  err = insert_revoke_hash(journal, blocknr,
402  handle->h_transaction->t_tid);
403  BUFFER_TRACE(bh_in, "exit");
404  return err;
405 }
406 
407 /*
408  * Cancel an outstanding revoke. For use only internally by the
409  * journaling code (called from journal_get_write_access).
410  *
411  * We trust buffer_revoked() on the buffer if the buffer is already
412  * being journaled: if there is no revoke pending on the buffer, then we
413  * don't do anything here.
414  *
415  * This would break if it were possible for a buffer to be revoked and
416  * discarded, and then reallocated within the same transaction. In such
417  * a case we would have lost the revoked bit, but when we arrived here
418  * the second time we would still have a pending revoke to cancel. So,
419  * do not trust the Revoked bit on buffers unless RevokeValid is also
420  * set.
421  *
422  * The caller must have the journal locked.
423  */
424 int journal_cancel_revoke(handle_t *handle, struct journal_head *jh)
425 {
426  struct jbd_revoke_record_s *record;
427  journal_t *journal = handle->h_transaction->t_journal;
428  int need_cancel;
429  int did_revoke = 0; /* akpm: debug */
430  struct buffer_head *bh = jh2bh(jh);
431 
432  jbd_debug(4, "journal_head %p, cancelling revoke\n", jh);
433 
434  /* Is the existing Revoke bit valid? If so, we trust it, and
435  * only perform the full cancel if the revoke bit is set. If
436  * not, we can't trust the revoke bit, and we need to do the
437  * full search for a revoke record. */
438  if (test_set_buffer_revokevalid(bh)) {
439  need_cancel = test_clear_buffer_revoked(bh);
440  } else {
441  need_cancel = 1;
442  clear_buffer_revoked(bh);
443  }
444 
445  if (need_cancel) {
446  record = find_revoke_record(journal, (unsigned long)bh->b_blocknr);
447  if (record) {
448  jbd_debug(4, "cancelled existing revoke on "
449  "blocknr %llu\n", (u64)bh->b_blocknr);
450  jbd_lock(&journal->j_revoke_lock);
451  list_del(&record->hash);
452  jbd_unlock(&journal->j_revoke_lock);
454  did_revoke = 1;
455  }
456  }
457 
458 #ifdef JBD_EXPENSIVE_CHECKING
459  /* There better not be one left behind by now! */
460  record = find_revoke_record(journal, bh->b_blocknr);
461  J_ASSERT_JH(jh, record == NULL);
462 #endif
463 
464  /* Finally, have we just cleared revoke on an unhashed
465  * buffer_head? If so, we'd better make sure we clear the
466  * revoked status on any hashed alias too, otherwise the revoke
467  * state machine will get very upset later on. */
468  if (need_cancel) {
469  struct buffer_head *bh2;
470  bh2 = __find_get_block(bh->b_bdev, bh->b_blocknr, bh->b_size);
471  if (bh2) {
472  if (bh2 != bh)
473  clear_buffer_revoked(bh2);
474  __brelse(bh2);
475  }
476  }
477  return did_revoke;
478 }
479 
480 /* journal_switch_revoke table select j_revoke for next transaction
481  * we do not want to suspend any processing until all revokes are
482  * written -bzzz
483  */
484 void journal_switch_revoke_table(journal_t *journal)
485 {
486  int i;
487 
488  if (journal->j_revoke == journal->j_revoke_table[0])
489  journal->j_revoke = journal->j_revoke_table[1];
490  else
491  journal->j_revoke = journal->j_revoke_table[0];
492 
493  for (i = 0; i < journal->j_revoke->hash_size; i++)
494  INIT_LIST_HEAD(&journal->j_revoke->hash_table[i]);
495 }
496 
497 /*
498  * Write revoke records to the journal for all entries in the current
499  * revoke hash, deleting the entries as we go.
500  *
501  * Called with the journal lock held.
502  */
503 
504 void journal_write_revoke_records(journal_t *journal,
505  transaction_t *transaction)
506 {
507  struct journal_head *descriptor;
508  struct jbd_revoke_record_s *record;
509  struct jbd_revoke_table_s *revoke;
510  struct list_head *hash_list;
511  int i, offset, count;
512 
513  descriptor = NULL;
514  offset = 0;
515  count = 0;
516 
517  /* select revoke table for committing transaction */
518  revoke = journal->j_revoke == journal->j_revoke_table[0] ?
519  journal->j_revoke_table[1] : journal->j_revoke_table[0];
520 
521  for (i = 0; i < revoke->hash_size; i++) {
522  hash_list = &revoke->hash_table[i];
523 
524  while (!list_empty(hash_list)) {
525  record = (struct jbd_revoke_record_s *)
526  hash_list->next;
527  write_one_revoke_record(journal, transaction,
528  &descriptor, &offset,
529  record);
530  count++;
531  list_del(&record->hash);
533  }
534  }
535  if (descriptor)
536  flush_descriptor(journal, descriptor, offset);
537  jbd_debug(1, "Wrote %d revoke records\n", count);
538 }
539 
540 /*
541  * Write out one revoke record. We need to create a new descriptor
542  * block if the old one is full or if we have not already created one.
543  */
544 
545 static void write_one_revoke_record(journal_t *journal,
546  transaction_t *transaction,
547  struct journal_head **descriptorp,
548  int *offsetp,
549  struct jbd_revoke_record_s *record)
550 {
551  struct journal_head *descriptor;
552  int offset;
554 
555  /* If we are already aborting, this all becomes a noop. We
556  still need to go round the loop in
557  journal_write_revoke_records in order to free all of the
558  revoke records: only the IO to the journal is omitted. */
559  if (is_journal_aborted(journal))
560  return;
561 
562  descriptor = *descriptorp;
563  offset = *offsetp;
564 
565  /* Make sure we have a descriptor with space left for the record */
566  if (descriptor) {
567  if (offset == journal->j_blocksize) {
568  flush_descriptor(journal, descriptor, offset);
569  descriptor = NULL;
570  }
571  }
572 
573  if (!descriptor) {
574  descriptor = journal_get_descriptor_buffer(journal);
575  if (!descriptor)
576  return;
577  header = (journal_header_t *) &jh2bh(descriptor)->b_data[0];
578  header->h_magic = cpu_to_be32(JFS_MAGIC_NUMBER);
579  header->h_blocktype = cpu_to_be32(JFS_REVOKE_BLOCK);
580  header->h_sequence = cpu_to_be32(transaction->t_tid);
581 
582  /* Record it so that we can wait for IO completion later */
583  JBUFFER_TRACE(descriptor, "file as BJ_LogCtl");
584  journal_file_buffer(descriptor, transaction, BJ_LogCtl);
585 
587  *descriptorp = descriptor;
588  }
589 
590  * ((__be32 *)(&jh2bh(descriptor)->b_data[offset])) =
591  cpu_to_be32(record->blocknr);
592  offset += 4;
593  *offsetp = offset;
594 }
595 
596 /*
597  * Flush a revoke descriptor out to the journal. If we are aborting,
598  * this is a noop; otherwise we are generating a buffer which needs to
599  * be waited for during commit, so it has to go onto the appropriate
600  * journal buffer list.
601  */
602 
603 static void flush_descriptor(journal_t *journal,
604  struct journal_head *descriptor,
605  int offset)
606 {
608  struct buffer_head *bh = jh2bh(descriptor);
609 
610  if (is_journal_aborted(journal)) {
611  put_bh(bh);
612  return;
613  }
614 
615  header = (journal_revoke_header_t *) jh2bh(descriptor)->b_data;
616  header->r_count = cpu_to_be32(offset);
617  set_buffer_jwrite(bh);
618  BUFFER_TRACE(bh, "write");
619  set_buffer_dirty(bh);
620  ll_rw_block(SWRITE, 1, &bh);
621 }
622 #endif
623 
624 /*
625  * Revoke support for recovery.
626  *
627  * Recovery needs to be able to:
628  *
629  * record all revoke records, including the tid of the latest instance
630  * of each revoke in the journal
631  *
632  * check whether a given block in a given transaction should be replayed
633  * (ie. has not been revoked by a revoke record in that or a subsequent
634  * transaction)
635  *
636  * empty the revoke table after recovery.
637  */
638 
639 /*
640  * First, setting revoke records. We create a new revoke record for
641  * every block ever revoked in the log as we scan it for recovery, and
642  * we update the existing records if we find multiple revokes for a
643  * single block.
644  */
645 
646 int journal_set_revoke(journal_t *journal,
647  unsigned long blocknr,
648  tid_t sequence)
649 {
650  struct jbd_revoke_record_s *record;
651 
652  record = find_revoke_record(journal, blocknr);
653  if (record) {
654  /* If we have multiple occurrences, only record the
655  * latest sequence number in the hashed record */
656  if (tid_gt(sequence, record->sequence))
657  record->sequence = sequence;
658  return 0;
659  }
660  return insert_revoke_hash(journal, blocknr, sequence);
661 }
662 
663 /*
664  * Test revoke records. For a given block referenced in the log, has
665  * that block been revoked? A revoke record with a given transaction
666  * sequence number revokes all blocks in that transaction and earlier
667  * ones, but later transactions still need replayed.
668  */
669 
670 int journal_test_revoke(journal_t *journal,
671  unsigned long blocknr,
672  tid_t sequence)
673 {
674  struct jbd_revoke_record_s *record;
675 
676  record = find_revoke_record(journal, blocknr);
677  if (!record)
678  return 0;
679  if (tid_gt(sequence, record->sequence))
680  return 0;
681  return 1;
682 }
683 
684 /*
685  * Finally, once recovery is over, we need to clear the revoke table so
686  * that it can be reused by the running filesystem.
687  */
688 
689 void journal_clear_revoke(journal_t *journal)
690 {
691  int i;
692  struct list_head *hash_list;
693  struct jbd_revoke_record_s *record;
694  struct jbd_revoke_table_s *revoke;
695 
696  revoke = journal->j_revoke;
697 
698  for (i = 0; i < revoke->hash_size; i++) {
699  hash_list = &revoke->hash_table[i];
700  while (!list_empty(hash_list)) {
701  record = (struct jbd_revoke_record_s*) hash_list->next;
702  list_del(&record->hash);
704  }
705  }
706 }
static unsigned int block
Definition: xmlmemory.c:118
kmem_cache_t * kmem_cache_create(const char *name, size_t size, size_t offset, unsigned long flags, kmem_cache_cb_t ctor)
Definition: linux.c:48
static int insert_revoke_hash(journal_t *journal, unsigned long blocknr, tid_t seq)
Definition: revoke.c:119
#define JFS_FEATURE_INCOMPAT_REVOKE
Definition: jbd.h:271
static void list_add(struct list_entry *entry, struct list_entry *prev, struct list_entry *next)
Definition: list.h:64
#define cpu_to_be32
Definition: module.h:154
#define is_power_of_2(x)
Definition: memory.c:2294
#define shift
Definition: input.c:1668
int __init journal_init_revoke_caches(void)
Definition: revoke.c:170
int journal_test_revoke(journal_t *journal, unsigned long blocknr, tid_t sequence)
Definition: revoke.c:670
#define SLAB_HWCACHE_ALIGN
Definition: module.h:1121
struct list_head * hash_table
Definition: revoke.c:95
static void list_del(struct list_head *entry)
Definition: list.h:89
Definition: arc.h:39
GLuint GLuint GLsizei count
Definition: gl.h:1545
tid_t
Definition: ieframe.h:311
int journal_init_revoke(journal_t *journal, int hash_size)
Definition: revoke.c:201
#define INIT_LIST_HEAD(ptr)
Definition: list.h:24
static void put_bh(struct buffer_head *bh)
Definition: module.h:939
static int tid_gt(tid_t x, tid_t y)
Definition: jbd.h:1085
void journal_destroy_revoke_caches(void)
Definition: revoke.c:191
GLintptr offset
Definition: glext.h:5920
struct list_head * next
Definition: list.h:16
#define GFP_NOFS
Definition: module.h:659
void * kmem_cache_alloc(kmem_cache_t *kc, int flags)
Definition: linux.c:92
#define GFP_KERNEL
Definition: module.h:658
size_t b_size
Definition: module.h:724
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glext.h:5644
void ll_rw_block(int, int, struct buffer_head *bh[])
Definition: linux.c:854
#define BJ_LogCtl
Definition: jbd.h:1123
Definition: arc.h:48
struct journal_revoke_header_s journal_revoke_header_t
static void brelse(struct buffer_head *bh)
Definition: module.h:945
void journal_clear_revoke(journal_t *journal)
Definition: revoke.c:689
Definition: list.h:15
struct journal_head * journal_get_descriptor_buffer(journal_t *journal)
Definition: replay.c:518
while(1)
Definition: macro.lex.yy.c:740
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static int hash(journal_t *journal, unsigned long block)
Definition: revoke.c:109
#define JFS_MAGIC_NUMBER
Definition: jbd.h:159
smooth NULL
Definition: ftsmooth.c:416
struct block_device * b_bdev
Definition: module.h:721
#define JFS_REVOKE_BLOCK
Definition: jbd.h:173
#define might_sleep()
Definition: module.h:440
static struct kmem_cache * revoke_record_cache
Definition: revoke.c:73
blkcnt_t b_blocknr
Definition: module.h:723
unsigned long blocknr
Definition: revoke.c:84
int journal_forget(handle_t *handle, struct buffer_head *bh)
Definition: replay.c:1447
void __brelse(struct buffer_head *)
Definition: linux.c:800
ULONG64 u64
Definition: btrfs.h:15
int journal_set_features(journal_t *journal, unsigned long compat, unsigned long ro, unsigned long incompat)
Definition: replay.c:804
void kmem_cache_free(kmem_cache_t *kc, void *p)
Definition: linux.c:103
static struct message * sequence
Definition: subclass.c:48
#define yield()
Definition: module.h:439
#define err(...)
#define __init
Definition: compat.h:3
static int repeat
Definition: xmllint.c:143
struct buffer_head * __find_get_block(struct block_device *bdev, sector_t block, unsigned long size)
Definition: linux.c:924
int kmem_cache_destroy(kmem_cache_t *kc)
Definition: linux.c:82
__WINE_SERVER_LIST_INLINE int list_empty(const struct list *list)
Definition: list.h:143
#define SLAB_TEMPORARY
Definition: module.h:1123
void * kmalloc(size_t, int)
__u32 __bitwise __be32
Definition: types.h:63
Definition: arc.h:40
struct transaction_s transaction_t
Definition: journal-head.h:14
#define SWRITE
Definition: module.h:1168
static struct jbd_revoke_record_s * find_revoke_record(journal_t *journal, unsigned long blocknr)
Definition: revoke.c:149
void journal_file_buffer(struct journal_head *jh, transaction_t *transaction, int jlist)
Definition: replay.c:1408
Definition: _hash_fun.h:40
#define __FUNCTION__
Definition: types.h:112
#define UL
Definition: tui.h:83
static struct kmem_cache * revoke_table_cache
Definition: revoke.c:74
struct CFHEADER header
Definition: fdi.c:109
void journal_destroy_revoke(journal_t *journal)
Definition: revoke.c:271
int journal_set_revoke(journal_t *journal, unsigned long blocknr, tid_t sequence)
Definition: revoke.c:646
void kfree(const void *)